2017-03-05 8 views
1

円弧の回転のこの線形複雑さの実装は正しいですか?アルゴリズム - 円形配列の回転

N =要素の数が K =回転

int write_to  = 0; 
    int copy_current = 0; 
    int copy_final = a[0]; 
    int rotation  = k; 
    int position  = 0; 

    for (int i = 0; i < n; i++) { 
     write_to  = (position + rotation) % n; 
     copy_current = a[write_to]; 
     a[write_to] = copy_final; 
     position  = write_to; 
     copy_final = copy_current; 
    } 
+0

まあ、複雑さは確かに線形です。しかし、配列内の値を '#rotation 'の位置でずらして回転させることを期待するならば、これは伝統的に循環ローテーションと呼ばれていますが、これが最終的なものでないときには驚くでしょう。 –

+0

http://stackoverflow.com/questions/11893053/circular-left-shift-of-an-array-by-n-positions-in-java – vadim

+2

@vadim:その質問に対する受け入れられた答えは確かに正しいですが、よりきれいです1.最初のk要素を逆にする。 2.残りの要素を反転させます。 3.アレイ全体を逆にする。 (逆転はすべてインプレースです) – rici

答えて

0

の数がこの例を考えます。

#include <iostream> 

int main(void) { 
    int n = 6; 
    int k = 2; 
    int a[] = {1, 2, 3, 4, 5, 6}; 

    int write_to  = 0; 
    int copy_current = 0; 
    int copy_final = a[0]; 
    int rotation  = k; 
    int position  = 0; 

    for (int i = 0; i < n; i++) { 
     write_to  = (position + rotation) % n; 
     copy_current = a[write_to]; 
     a[write_to] = copy_final; 
     position  = write_to; 
     copy_final = copy_current; 
    } 

    for (int i = 0; i < n; i++) { 
     std::cout << a[i] << (i + 1 < n ? ' ' : '\n'); 
    } 
    return 0; 
} 

期待される結果:

5 6 1 2 3 4 

実際の結果:STLを使用して::

3 2 1 4 1 6 
0

がのstd ::アレイ上で回転させ、あなたは左のように、2を言う、ことによって回転することができます

std::array<int, 6> a{1, 2, 3, 4, 5, 6}; 
std::rotate(begin(a), begin(a) + 2, end(a)); // left rotate by 2 

:3 4 5 6 1 2またはright-ro

std::rotate(begin(a), end(a) - 2, end(a)); // right rotate by 2 

となり、線形の複雑さを伴います。

0

kの長さがの配列をleftまたはrightの方向に回転させます。

public enum Direction { 
    L, R 
}; 

回転timesdirection有する:

public static final void rotate(int[] arr, int times, Direction direction) { 
    if (arr == null || times < 0) { 
     throw new IllegalArgumentException("The array must be non-null and the order must be non-negative"); 
    } 
    int offset = arr.length - times % arr.length; 
    if (offset > 0) { 
     int[] copy = arr.clone(); 
     for (int i = 0; i < arr.length; ++i) { 
      int j = (i + offset) % arr.length; 
      if (Direction.R.equals(direction)) { 
       arr[i] = copy[j]; 
      } else { 
       arr[j] = copy[i]; 
      } 
     } 
    } 
} 

複雑:O(N

コードは

私は方向列挙定義Javaであります)。

例: 入力:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 回し3left 出力:[4, 5, 6, 7, 8, 9, 10, 1, 2, 3]

入力:[4, 5, 6, 7, 8, 9, 10, 1, 2, 3] 回し3right 出力:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

+0

これは疑問に答えるかもしれませんが、答えの本質的な部分を説明するのが良いでしょう。 – pirho

+0

あなたは質問に答えませんでした(「循環配列回転の線形複雑さの実装は正しいのですか?」)。理由と理由を説明すると、いつも感謝しています。 – fragmentedreality