我想改变std::swap
forchar
类型的行为。根据我所了解到的,唯一的方法是添加模板特化 for std::swap
,不是吗?
由于char
是内置类型,我们没有机会使用 ADL。
请就此类情况提出您的建议。
编辑:这是我需要解决的原始问题。随机打乱字符串,但非字母字符应保持其位置不变。
我想做的第一件事是利用std::random_shuffle
.
我想改变std::swap
forchar
类型的行为。根据我所了解到的,唯一的方法是添加模板特化 for std::swap
,不是吗?
由于char
是内置类型,我们没有机会使用 ADL。
请就此类情况提出您的建议。
编辑:这是我需要解决的原始问题。随机打乱字符串,但非字母字符应保持其位置不变。
我想做的第一件事是利用std::random_shuffle
.
第一:不要那样做。您可能无意中破坏了以前工作的代码的不同部分。
您可以尝试创建自己的类,使其仅包含一个char
元素,然后向其中添加您喜欢的任何花哨的功能。这样,您将拥有自己的swap
行为而不会破坏其他人的代码。
但是,如果您仍然想这样做,请尝试以下(运行)示例:
#include <algorithm>
#include <iostream>
namespace std {
template <>
void swap<char>(char& a, char& b) {
std::cerr << "Swapped " << a << " with " << b << "\n";
char t=a;
a=b;
b=t;
}
}
int main() {
char arr[] = {'a', 'z', 'b', 'y'};
std::reverse(arr, arr+4);
return 0;
}
请注意,某些 stl 算法可能专门针对基本类型而根本不使用std::swap
。
广告。编辑问题:
公平洗牌算法相当简单:
for (i = 0 .. n-2) {
j = random (i .. n-1); //and NOT random (0 .. n-1)
swap(array[i], array[j]);
}
但是,如果您swap
在任何一个参数不是字母数字时进行修改以阻止操作(我想这就是您想要将交换更改为的内容?),那么剩余的排列将不公平。随着非字母数字字符数量的增加,给定字符不会移动的机会 - 增加。在最坏的情况下,想象一个只有两个字母数字字符的长字符串——它们被交换的机会将接近 0。
如果您只想对非字母字符进行公平排列,您可以这样做:
a)非常简单的方法 - 提取字母数字字符以分隔数组,随机播放,然后将它们放回原处。
简单,不会影响性能,但需要更多内存。
b) 如果非字母数字字符的数量相对较少,您可以重复掷骰子:
for (i = 0 .. n-2) {
if (!alphanumeric(array[i]) continue;
do {
j = random (i .. n-1);
while (!alphanumeric(array[j]));
swap(array[i], array[j]);
}
这种改组仍然是公平的,但是当您有很多非字母数字字符时会花费很多时间。