生成随机字母数组并计算出现次数
Generate random letter array and count occurences
您好,我正在尝试生成用户输入长度的随机数组。然后我的数组应该打印并显示数组中这些字母的出现。到目前为止,这只打印到字母 g,并且出现的次数不正确。如果有人能告诉我我做错了什么,那会有很大帮助。谢谢。
#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand(time(0));
int i, num;
char ch;
char chars[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int freq[26]={0};
cout << "How many letters do you want in your string? ";
cin >> num;
for (i=0; i < num; i++)
{
ch = chars[rand()%26];
chars[i]=ch;
freq[i] +=1;
cout << ch;
}
for (char lower = 'a'; lower <='z'; lower++)
{
cout << "\nLetter" << lower << "is " << freq[lower] << "times";
}
}
问题 1
线条
chars[i]=ch;
freq[i] +=1;
不对。您需要使用:
int index = ch - 'a';
freq[index] += 1;
问题 2
用于打印数据的 for
循环中的索引也不正确。
您需要使用:
for (char lower = 'a'; lower <='z'; lower++)
{
int index = lower - 'a';
cout << "\nLetter" << lower << "is " << freq[index] << "times";
}
重要提示
值得注意的是,C++标准并不保证小写字母是连续的。 (感谢@MartinBonner)。例如,如果您的系统使用 EBCDIC encoding,您的程序将无法运行。
为了使您的代码健壮,最好使用 std::map
。
int main()
{
srand(time(0));
int i, num;
char ch;
char chars[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
std::map<char, int> freq;
// Initialize freq.
for ( ch : chars )
{
freq[ch] = 0;
}
cout << "How many letters do you want in your string? ";
cin >> num;
for (i=0; i < num; i++)
{
ch = chars[rand()%26];
freq[ch] +=1;
}
for (auto item : freq )
{
cout << "\nLetter" << item.first << "is " << item.second << "times";
}
}
您不应该写入 chars
,并且 freq
应该被扩展以覆盖 a...z 范围(ASCII 代码),但事实并非如此。此外,在索引 ch
处增加,而不是在 i
.
处增加
我什至不知道我头脑中的那个范围,但可以修改它以跟踪所有可能的字节而不是 (0...255),请参阅 https://ideone.com/xPGls7[=22= 上的结果]
变更列表:
int freq[256]={0}; // instead of int freq[26]={0};
// chars[i]=ch; is removed
freq[ch] +=1; // instead of freq[i] +=1;
然后就可以了。
你可能想看看 C++11 Pseudo-random number generation 这里有一个生成你想要的范围的简短方法:
#include <algorithm>
#include <array>
#include <random>
#include <vector>
using namespace std;
int main()
{
int arraySize = 35;
mt19937 engine{random_device{}()};
uniform_int_distribution<> dist{'a', 'z'};
vector<char> vec;
generate_n(back_inserter(vec), arraySize, [&]() { return static_cast<char>(dist(engine); }));
//To count occurrences
array<int, 26> freq;
for (auto c : vec) { ++freq[c-'a']; }
return 0;
}
使用 lambda 函数完成大部分工作。
#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <ostream>
#include <random>
#include <string>
#include <utility>
#include <vector>
using namespace std::string_literals;
int main()
{
std::mt19937::result_type seed = std::random_device{}();
auto engine = std::mt19937(seed);
auto dist = std::uniform_int_distribution<>('a', 'z');
auto random_letter = [&engine, &dist]() { return static_cast<char>(dist(engine)); };
std::cout << "How many letters do you want to generate? "s;
int n;
if (!(std::cin >> n)) { return EXIT_FAILURE; }
auto letters = std::vector<char>();
std::generate_n(std::back_inserter(letters), n, random_letter);
auto zero = std::map<char, int>();
auto const frequencies = std::accumulate(std::cbegin(letters), std::cend(letters), zero,
[](auto& acc, auto c)
{
++acc[c];
return acc;
});
for (auto const [c, freq] : frequencies)
{
std::cout << "The letter '"s << c << "' appeared "s << freq << " times." << std::endl;
}
return 0;
}
您好,我正在尝试生成用户输入长度的随机数组。然后我的数组应该打印并显示数组中这些字母的出现。到目前为止,这只打印到字母 g,并且出现的次数不正确。如果有人能告诉我我做错了什么,那会有很大帮助。谢谢。
#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand(time(0));
int i, num;
char ch;
char chars[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int freq[26]={0};
cout << "How many letters do you want in your string? ";
cin >> num;
for (i=0; i < num; i++)
{
ch = chars[rand()%26];
chars[i]=ch;
freq[i] +=1;
cout << ch;
}
for (char lower = 'a'; lower <='z'; lower++)
{
cout << "\nLetter" << lower << "is " << freq[lower] << "times";
}
}
问题 1
线条
chars[i]=ch;
freq[i] +=1;
不对。您需要使用:
int index = ch - 'a';
freq[index] += 1;
问题 2
用于打印数据的 for
循环中的索引也不正确。
您需要使用:
for (char lower = 'a'; lower <='z'; lower++)
{
int index = lower - 'a';
cout << "\nLetter" << lower << "is " << freq[index] << "times";
}
重要提示
值得注意的是,C++标准并不保证小写字母是连续的。 (感谢@MartinBonner)。例如,如果您的系统使用 EBCDIC encoding,您的程序将无法运行。
为了使您的代码健壮,最好使用 std::map
。
int main()
{
srand(time(0));
int i, num;
char ch;
char chars[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
std::map<char, int> freq;
// Initialize freq.
for ( ch : chars )
{
freq[ch] = 0;
}
cout << "How many letters do you want in your string? ";
cin >> num;
for (i=0; i < num; i++)
{
ch = chars[rand()%26];
freq[ch] +=1;
}
for (auto item : freq )
{
cout << "\nLetter" << item.first << "is " << item.second << "times";
}
}
您不应该写入 chars
,并且 freq
应该被扩展以覆盖 a...z 范围(ASCII 代码),但事实并非如此。此外,在索引 ch
处增加,而不是在 i
.
我什至不知道我头脑中的那个范围,但可以修改它以跟踪所有可能的字节而不是 (0...255),请参阅 https://ideone.com/xPGls7[=22= 上的结果] 变更列表:
int freq[256]={0}; // instead of int freq[26]={0};
// chars[i]=ch; is removed
freq[ch] +=1; // instead of freq[i] +=1;
然后就可以了。
你可能想看看 C++11 Pseudo-random number generation 这里有一个生成你想要的范围的简短方法:
#include <algorithm>
#include <array>
#include <random>
#include <vector>
using namespace std;
int main()
{
int arraySize = 35;
mt19937 engine{random_device{}()};
uniform_int_distribution<> dist{'a', 'z'};
vector<char> vec;
generate_n(back_inserter(vec), arraySize, [&]() { return static_cast<char>(dist(engine); }));
//To count occurrences
array<int, 26> freq;
for (auto c : vec) { ++freq[c-'a']; }
return 0;
}
使用 lambda 函数完成大部分工作。
#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <ostream>
#include <random>
#include <string>
#include <utility>
#include <vector>
using namespace std::string_literals;
int main()
{
std::mt19937::result_type seed = std::random_device{}();
auto engine = std::mt19937(seed);
auto dist = std::uniform_int_distribution<>('a', 'z');
auto random_letter = [&engine, &dist]() { return static_cast<char>(dist(engine)); };
std::cout << "How many letters do you want to generate? "s;
int n;
if (!(std::cin >> n)) { return EXIT_FAILURE; }
auto letters = std::vector<char>();
std::generate_n(std::back_inserter(letters), n, random_letter);
auto zero = std::map<char, int>();
auto const frequencies = std::accumulate(std::cbegin(letters), std::cend(letters), zero,
[](auto& acc, auto c)
{
++acc[c];
return acc;
});
for (auto const [c, freq] : frequencies)
{
std::cout << "The letter '"s << c << "' appeared "s << freq << " times." << std::endl;
}
return 0;
}