代码之家  ›  专栏  ›  技术社区  ›  Casey

保证:

  •  -2
  • Casey  · 技术社区  · 6 年前

    有办法保证 std::shuffle 产生与输入不同的输出?

    下面是一个有趣的例子,我在玩一些旧代码,除了第一个和最后一个字母外,这些旧代码会洗牌一个单词中的字母。我注意到对于短序列 STD:洗牌 会“随机”地将字母洗牌到它们原来的位置并产生不希望的输出。所以为了“解决”这个问题我重新运行 STD:洗牌 再一次。

    简单地说,有没有办法避免while循环,或者它只是 STD:洗牌 ?

    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 回复  |  直到 6 年前
        1
  •  -1
  •   Casey    6 年前

    不。

    std::shuffle 按预期工作并返回给定序列的随机排列。即使和输入一样。

    在不需要的输出上重新滚动序列是最简单的解决方案,而且很可能“唯一的洗牌”无论如何都会完成。