Генерация случайного массива букв и подсчет вхождений - PullRequest
0 голосов
/ 08 ноября 2019

Здравствуйте. Я пытаюсь сгенерировать случайный массив длины, который вводит пользователь. Мой массив должен затем напечатать и отобразить вхождения этих букв в массив. До сих пор это только печатает до буквы 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";
    }
}

Ответы [ 4 ]

2 голосов
/ 08 ноября 2019

Задача 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 , ваша программа не будет работать.

Чтобы сделать ваш код устойчивым, будет лучше использовать 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 голос
/ 08 ноября 2019

Возможно, вы захотите взглянуть на C ++ 11 Генерация псевдослучайных чисел Вот краткий способ генерации диапазона, который вы хотите использовать с помощью этого:

#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 голосов
/ 09 ноября 2019

Использование лямбда-функций для выполнения большей части работы.

#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;
}
0 голосов
/ 08 ноября 2019

Вы не должны писать в 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;

Тогда это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...