Гарантия std :: shuffle возвращает уникальную последовательность - PullRequest
0 голосов
/ 01 декабря 2018

Есть ли способ гарантировать, что std::shuffle выдаст вывод, который не совпадает с вводом?

Ниже приведен игрушечный пример, где я играл с каким-то старым кодом, который бы перемешивал буквыОдним словом, кроме первого и последнего.Я заметил, что для коротких последовательностей std::shuffle будет «случайным образом» перетасовывать буквы в их исходные позиции и производить нежелательный вывод.Таким образом, чтобы «исправить» проблему, я просто заново запускаю std::shuffle.

Проще говоря, есть ли способ избежать цикла while или это просто причудливость std::shuffle?

std::string Scramble(const std::string& plaintext) {

    static std::random_device rd;
    static std::mt19937 g(rd());

    std::stringstream ss;
    ss << plaintext;

    std::vector<std::string> words{};
    std::string cur_word;
    while(std::getline(ss, cur_word, ' ')) {
        if(cur_word.empty()) continue;
        words.push_back(cur_word);
    }

    std::for_each(std::begin(words), std::end(words), [](std::string& word) {
        if(word.size() <= 3) {
            return;
        }
        auto old_word = word;
        while(old_word == word) {
            std::shuffle(std::begin(word) + 1, std::end(word) - 1, g);
        }
    });

    ss.clear();
    ss.seekg(0);
    ss.seekp(0);
    ss.str("");

    for(const auto& word : words) {
        ss << word << ' ';
    }

    return ss.str();
}

1 Ответ

0 голосов
/ 01 декабря 2018

Нет.

std::shuffle работает так, как задумано, и возвращает случайную перестановку заданной последовательности.Даже если он совпадает с вводом.

Повторная последовательность на нежелательном выводе - самое простое решение и, скорее всего, то, что в любом случае достигнет "уникальный тасовка".

...