0

std::swapforchar型の動作を変更したい。私が学んだことによると、これを行う唯一の方法は、テンプレートの特殊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引数のいずれかが英数字ではない場合に操作を防止するように変更すると (スワップを変更したかったと思いますか?)、残りの順列は公平ではありません。英数字以外の文字の数が増えると、特定の文字が動かない可能性が高くなります。最悪のシナリオでは、英数字が 2 文字しかない長い文字列を想像してみてください。それらが入れ替わる可能性はほぼ 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 に答える