生成随机字母数组并计数出现次数

问题描述 投票:0回答:4

您好,我正在尝试生成用户输入长度的随机数组。然后,我的阵列应打印并显示这些字母在阵列中的出现情况。到目前为止,这仅打印到字母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";
    }
}
c++ arrays random frequency srand
4个回答
2
投票

问题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";
    }
}

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;
}

0
投票

您不应该写入chars,并且应该扩展freq以覆盖a ... z范围(ASCII码),但不能。另外,在索引ch处增加,而不在i处增加。

我什至都不知道从我头顶开始的范围,但是可以修改它以跟踪所有可能的字节(0 ... 255),请参见https://ideone.com/xPGls7更改列表:

int freq[256]={0}; // instead of int freq[26]={0};
// chars[i]=ch; is removed
freq[ch] +=1; // instead of freq[i] +=1;

然后它起作用。


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.