保证std::shufflereturns唯一序列
Guarantee std::shuffle returns unique sequence
有没有办法保证 std::shuffle
产生与输入不同的输出?
下面是一个玩具示例,我在其中玩弄一些旧代码,这些代码会打乱单词中除第一个和最后一个字母之外的字母。我注意到对于短序列 std::shuffle
会 "randomly" 将字母洗牌到它们的原始位置并产生不需要的输出。所以对于"fix"这个问题我只是重新运行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();
}
没有
std::shuffle
按预期工作,returns 给定序列的随机排列。哪怕和输入的一样。
在不需要的输出上重新滚动序列是最简单的解决方案,而且“独特的洗牌”很可能无论如何都会完成。
有没有办法保证 std::shuffle
产生与输入不同的输出?
下面是一个玩具示例,我在其中玩弄一些旧代码,这些代码会打乱单词中除第一个和最后一个字母之外的字母。我注意到对于短序列 std::shuffle
会 "randomly" 将字母洗牌到它们的原始位置并产生不需要的输出。所以对于"fix"这个问题我只是重新运行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();
}
没有
std::shuffle
按预期工作,returns 给定序列的随机排列。哪怕和输入的一样。
在不需要的输出上重新滚动序列是最简单的解决方案,而且“独特的洗牌”很可能无论如何都会完成。