Как написать генератор случайных символов в верхнем регистре в C ++? - PullRequest
3 голосов
/ 14 января 2020

Мой взгляд на это был бы

#include <iostream>

int main()
{
    for( int i = 0; i < 20; ++i) {
        std::cout << (char) ((random() % (int('Z') + 1)) + int('A'))  << '\n';
    }
}

Это кажется очень прямым. Вы генерируете число, которое находится между всем ниже или равно Z и больше или равно A. Если вы играете с ним , вы обнаружите, что генерируются и другие символы. Почему это так?

Ответы [ 6 ]

8 голосов
/ 14 января 2020

С <random> и без ASCII вы можете сделать:

const std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
constexpr std::size_t output_size = 20;
std::mt19937 rng{std::random_device{}()};
std::uniform_int_distribution<> dis(0, alphabet.size() - 1);
std::string res;
res.reserve(output_size);

std::generate_n(std::back_inserter(res),
                output_size,
                [&](){ return alphabet[dis()]; });
5 голосов
/ 14 января 2020
char c = *("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + rand() % 26);

является по крайней мере переносимым. Обратите внимание на использование арифметического указателя c на константе const char[27], которая затухает до const char* типа в выражении. Выключите rand() для чего-то из std::random, если вышеупомянутое не является достаточно случайным.

3 голосов
/ 14 января 2020

Ваша математика неверна. Предполагая, что ASCII, (random() % (int('Z') + 1) может вернуть что-либо до 'Z', включая строчные буквы, цифры, непечатные символы и другие вещи. Если вы добавите int('A') к этому, вы получите большое изменение при получении результата, который находится за пределами символов верхнего регистра, и даже более 127 и, следовательно, больше не ASCII.

Вы могли бы просто иметь 'A' + (random() % 26) вместо этого.

1 голос
/ 14 января 2020

Другой вариант - использовать std::shuffle. Вы можете использовать это, чтобы смешать ваш алфавит и взять первые N символов, которые вам нужны, из этой перемешанной строки. Это будет выглядеть как

std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::shuffle(alphabet.begin(), alphabet.end(), std::mt19937{std::random_device{}()});
std::cout << alphabet.substr(20); // N in this case
0 голосов
/ 14 января 2020

Ну, я бы так написал. Он просто отбирает ГСЧ в диапазоне от «А» до «Z», а затем переводит его в символ.

std::mt19937 rng{ std::random_device{}() };
std::uniform_int_distribution<> dis('A', 'Z');
std::cout << static_cast<char>(dis(rng));
0 голосов
/ 14 января 2020

'Z' равно 90, поэтому код:

(random() % (int('Z') + 1)

Создает числа от 1 до 90. Затем вы добавляете «А», равное 65, так что ваши числа находятся в диапазоне 66–155. Чтобы исправить это, вы должны изменить свой код на:

std::cout << (char) ((random() % (int('Z' - 'A') + 1)) + int('A'))  << '\n';
...