2010-12-15 3 views
1

정수의 원형 배열에서 왼쪽 시프트를 수행하는 기존 방법이 있습니까?원형 배열에서 왼쪽 시프트를 어떻게 수행합니까?

특히 {1,2,3,4}의 4 개 항목과 시프트 양이 2 인 배열이 주어지면 첫 번째 두 글자를 배열의 뒤쪽으로 이동하여 다음과 같이 표시하는 방법을 원합니다. {3,4,1,2}.

이 알고리즘은 순환 배열을 하나씩 이동시킬 수 있습니까? 만약 n로 이동하고자한다고 가정

algShiftByOne(Array) 
{ 
    temp=array[0]; 
    i=1 
    while(i < Array.length - 1) // Loop from 1 up to array.length == last index 
    { 
    // If there is no exception i assume it copies value from 
    // initial array starting from 1 up to array.length 
    Array[i - 1] = Array[i]; 
    i++; 
    } 
Array[Array.length]=temp; 
} 
+6

입니다 – zengr

+1

을 대부분의 경우 이러한 컴퓨터 과학의 미래 –

+0

가능한 중복.. [원형 이동을위한 가장 빠른 알고리즘] M posi의 N 크기 배열 (http://stackoverflow.com/questions/876293/fastest-algorithm-for-circle-shift-n-size-array-for-mposition) –

답변

0

:

  1. 복사 배열에서 첫 번째 N 개의 엘리먼트 이름, 예를 들면, 마지막에 n에서 각 요소 tempNumbers
  2. 시프트 왼쪽에서 왼쪽으로 n
  3. tempNumbers에서 원래 배열 끝까지 요소를 복사하십시오.
+1

이러한 요소를 별도의 배열로 복사 할 필요가 없습니다. . –

0

왜 원형 (중복) 연결 목록을 사용하지 않으십니까? 이 경우 '시작 포인터'만 변경하면됩니다.

+1

비용/성능에 대해 생각하십시오 – Sami

+0

성능이 빠릅니다 (시작 포인터 만 변경). 메모리 비용은 상대적으로 높습니다. – Jochem

+0

시간 (속도)면에서 성능을 고려하고 있습니다. 또한 공간 측면에서 성능 고려 사항이 있습니다. N 요소 배열의 경우, 이중 연결리스트는 크기 N (1 + 2M + B)입니다. 여기서 M은 포인터 참조의 크기이고 B는 = 페이로드 (원본 요소)와 포인터를 포함하는 노드 구조의 공간 오버 헤드 ... 그리고 이것은 배열에서 요소를 목록으로 복사 할 때 임시 공간 오버 헤드를 계산하지 않아도됩니다. 이 간단한 알고리즘에 대해서는 완전히 복잡합니다. –

0

다음은 원하는대로 의사 코드를 작성한 것입니다.

Array shift(Array a, int shiftLength) { 
    Array b; 

    for(i = shiftLength; i < a.size(); i++) 
     b.add(a.at(i)); 

    for(i = 0; i < shiftLength; i++) 
     b.add(a.at(i)); 

    return b; 
} 
+1

'System.arraycopy()'가 빠릅니다. – thejh

+0

@thejh 가능성이 있습니다. 이것이 원형 이동이 어떻게 수행되는지에 대한 좋은 시연이라고 생각합니다. –

+0

@thejh - System.arrayCopy는 그 자체만으로는 정의와 효율성으로 '임의의 원형 배열 n-shift'를 구현할 수 없습니다. System.arrayCopy를 사용하면 N 크기의 배열에서 n-shift를 수행하기 위해 임시 배열에 N-n 요소를 복사해야합니다. –

0

이렇게하면 배열이 하나 왼쪽으로 이동합니다.

int[] a = new int[] { 1, 2, 3, 4, 5 }; 
int[] b = new int[a.length]; 
System.arraycopy(a, 1, b, 0, a.length - 1); 
b[a.length - 1] = a[0]; 
// b = {2,3,4,5,1} 
// edit 
a = b; 
+2

* "이것은 배열을 왼쪽으로 1 개 시프트 할 것입니다."* 정확히 말하면 'a'의 내용은 변경되지 않습니다.) 그리고 btw는 빈 입력 배열을 조심하십시오 ... – aioobe

5

여기 (여기 ideone.com demo입니다) ... 그것에 내 이동이다 나는 면접 질문 등이 하나 있었다

import java.util.Arrays; 

public class Test { 

    public static void circularShiftLeft(int[] arr) { 
     if (arr.length == 0) 
      return; 

     int first = arr[0]; 
     System.arraycopy(arr, 1, arr, 0, arr.length - 1); 
     arr[arr.length - 1] = first; 
    } 

    public static void main(String[] arg) { 
     int[] arr = { 1, 2, 3, 4 }; 
     System.out.println(Arrays.toString(arr)); 
     circularShiftLeft(arr); 
     System.out.println(Arrays.toString(arr)); 
    } 
} 
4

. m을 회전시키는 간단한 (그리고 다소 직관적 인) O (2n) 솔루션은 배열을 가져 와서 역순으로 한 다음 [0, m] 및 (m, n) 하위 배열을 뒤집을 수 있습니다. , in place and O (n)입니다. 기본적으로 아이디어는 항목을 하나의 항목에서 앞으로 회전시키고 결국 모든 요소를 ​​통과하게됩니다. 배열은 거리의 배수가되는 경우입니다. 즉, GCD . 온 다음은 오른쪽으로 회전을 할 것입니다, 왼쪽 연습으로 독자에게 남아 회전 :이 숙제

public static void main(String[] args) { 
    int[] f = {0, 4, 8, 2, 6, 7, 4, 5, 3}; 
    System.out.println(Arrays.toString(f)); 
    rotate(f, 3); 
    System.out.println(Arrays.toString(f)); 
} 

public static void rotate(int[] arr, int dist){ 
    int tmp, tmp2, gcd = GCD(arr.length, dist); 
    for(int off=0;off<gcd;off++){ 
     tmp = arr[off]; 
     for(int i=0,idx=off;i<arr.length/gcd;idx=(idx+dist)%arr.length,i++){ 
      tmp2 = arr[(idx+dist)%arr.length]; 
      arr[(idx+dist)%arr.length] = tmp; 
      tmp = tmp2; 
     } 
    } 
} 

public static int GCD(int a, int b) { 
    if (b==0) return a; 
    return GCD(b,a%b); 
} 
+0

O (2n) is O (n)과 동일합니다. – aioobe

+0

나는 이것을 깨달았지만, 그것의 절반 밖에 작동하지 않는다는 것을 지적하고 싶었다. 작은 배열은 무시해도 좋지만 배열이 충분히 큰 경우에는 차이가 날 수 있습니다. –

0
public static void shift(int[] arr, int offs) { 
    // e.g. arr = 1,2,3,4,5,6,7,8,9; offs = 3 
    offs %= arr.length; 
    offs = offs < 0 ? arr.length + offs : offs; 

    if (offs > 0) { 
     // reverse whole array (arr = 9,8,7,6,5,4,3,2,1) 
     for (int i = 0, j = arr.length - 1; i < j; i++, j--) 
      swap(arr, i, j); 
     // reverse left part (arr = 7,8,9,6,5,4,3,2,1) 
     for (int i = 0, j = offs - 1; i < j; i++, j--) 
      swap(arr, i, j); 
     // reverse right part (arr = 7,8,9,1,2,3,4,5,6) 
     for (int i = offs, j = arr.length - 1; i < j; i++, j--) 
      swap(arr, i, j); 
    } 
} 

private static void swap(int[] arr, int i, int j) { 
    int tmp = arr[i]; 
    arr[i] = arr[j]; 
    arr[j] = tmp; 
} 
관련 문제