0

我想改变std::swapforchar类型的行为。根据我所了解到的,唯一的方法是添加模板特化 for std::swap,不是吗?

由于char是内置类型,我们没有机会使用 ADL。

请就此类情况提出您的建议。

编辑:这是我需要解决的原始问题。随机打乱字符串,但非字母字符应保持其位置不变。

我想做的第一件事是利用std::random_shuffle.

4

1 回答 1

2

第一:不要那样做。您可能无意中破坏了以前工作的代码的不同部分。

您可以尝试创建自己的类,使其仅包含一个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]);
}

这种改组仍然是公平的,但是当您有很多非字母数字字符时会花费很多时间。

于 2012-11-06T06:13:23.180 回答