标题非常明显,但这里有几个例子:
我认为std::random_shuffle(myString.begin(), myString.end())
会很有趣,因为它永远不会通过不同的调用进行相同的重新排序,但它需要循环,而结果字符串在连续位置没有相似的字符。是否有更合理的方法来进行重新排序,或者其他任何类似的功能?
注意:重新排序不需要随机完成。只要相同的字符不在连续的位置,就可以使用排序功能。
更新:正如评论中所述...是的random_shuffle 可以连续多次返回相同的字符串顺序。假设前面的方法,next_permutation
会更合适。
答案 0 :(得分:1)
首先请注意,解决方案并不总是存在。当且仅当出现次数最多的元素不超过(n+1)/2
时才存在。
因此很容易检查解决方案是否存在。如果它存在,那么以下代码将找到它
bool cmpBySecond(const std::pair<char, int>& a, const std::pair<char, int>& b) {
if (a.second == b.second) return a.first < b.first;
return a.second < b.second;
}
std::string reorder(const std::string& input) {
std::map<char, int> cnt;
for (auto& c: input) cnt[c]++;
auto items = std::vector<std::pair<char, int>>(cnt.begin(), cnt.end());
std::sort(items.begin(), items.end(), cmpBySecond);
std::reverse(items.begin(), items.end());
// now we have chars with occurencies counts in descending order
std::string result(input);
int pos = 0;
for (auto& it: items) {
char c = it.first;
int times = it.second;
for (int i = 0; i < times; ++i) {
result[pos] = c;
pos += 2;
if (pos >= result.size()) pos = 1;
}
}
return result;
}
超越它的想法是分配最频繁的元素,然后填补其余元素的空白。
同样的代码包含一些测试here。