あなたがしたい変換は、基本的に循環シフトであるn
(またはシフトの方向によってはm
)です。
例えば、我々は、この変換中に(私は2つのアレイを分離する文字と数字を使用) 1 2 3 4 5 6 7 a b c
を有する1
は4
の位置に移動し、4
は、7
にc
から7
を移動し、3
からc
、3
に6
など最終的には、開始位置の1
に戻ります。
そのときに1つの番号を移動して、完了しました。
変換を完了する前に1
に戻る場合があります。 1 2 a b c d
の場合と同様に、位置は1 -> a -> c -> 1
になります。この場合は、2
から始まり、操作を繰り返す必要があります。
私たちが必要とする反復量は、n
とm
の最大公約数です。
ので、コードが簡単にwell-known recursive formulaとO(logn)
で計算することができ
int repetitions = GCD(n, m);
int size = n + m;
for (int i = 0; i < repetitions; ++i) {
int current_number = a[i];
int j = i;
do {
j = (j + n) % size;
int tmp = current_number;
current_number = a[j];
a[j] = tmp;
} while (j != i);
}
最大公約数のようになります。
編集
それは仕事をし、私はJavaでみました。私は表現を簡単にするためにデータ型を文字列に変更しました。
String[] a = {"1", "2", "3", "4", "5", "6", "a", "b", "c"};
int n = 3;
int m = 6;
// code from above...
System.out.println(Arrays.toString(a));
そして、ユークリッドの式:私はあなたが一つ以上を作成することでごまかすことができない「メモリ内」で想定してい
int GCD(int a, int b) {
if (a == 0) {
return b;
}
return GCD(b % a, a);
}
ソートされていませんか? –
'a1'はいくつかの要素が' A'です。それは他の要素と並べ替えたり比較したりする必要はありません。「m」の位置を前方に移動するだけです。 –