2011-11-26 6 views
3

잠시 동안이 문제가 발생하여 여기에서 질문 할 것입니다. 기본적으로 원하는 최소 및 최대 인덱스 (최소 및 최대 인덱스는 0 주위로 회전 함)와 함께 일부 대상 배열에 주어진 최소 및 최대 인덱스를 사용하여 배열 값을 '자르기'해야하며 배열 크기는 최소 및 최대 사이의 차이를 존중합니다 . 실제 배열은 인덱스 0부터 시작하지만, 실제 데이터에 대한 오프셋은 다를 수 있습니다.원하는 min + max 인덱스를 가진 대상 배열에 min + max 인덱스가 지정된 자르기 배열 값

나는 그것에 가봤지만 (아래 참조), 나는 약간의 어려움을 겪고있다. 내 수학은 정말 가난하다. 이 코드는 실행하기 쉽도록 JUnit 테스트로 정렬되며 예상 결과가 무엇인지 확인할 수 있습니다. 지역 차이를 구별하는 알고리즘의 메커니즘이 좋은 것이라고는 생각하지 않습니다.보다 일반적인 솔루션이 있어야합니다. 모든 솔루션에 동일한 라인을 사용할 수 있어야합니다. 그런 것.

이것은 숙제가 아니거나, 그리드를 자르기위한 것이므로 그리드를 동적으로 축소하고 확대 할 수 있습니다. 이것은 단지 1 단계입니다.

어디서 잘못 됐습니까?

import static org.junit.Assert.*; 
import java.util.Arrays; 
import org.junit.Test; 

public class Hmm { 

    @Test 
    public void shrinkTest1() { 
     int[] res = arrMod(new int[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -1, 2); 
     int[] exp = new int[] { 4, 5, 6, 7 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void expandTest1() { 
     int[] res = arrMod(new int[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 4); 
     int[] exp = new int[] { 0, 3, 4, 5, 6, 7, 8, 0 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void expandTest2() { 
     int[] res = arrMod(new int[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 6); 
     int[] exp = new int[] { 0, 3, 4, 5, 6, 7, 8, 0, 0, 0 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void sameTest1() { 
     int[] res = arrMod(new int[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 2); 
     int[] exp = new int[] { 0, 3, 4, 5, 6, 7 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    public int[] arrMod(int[] data, int min, int max, int newmin, int newmax) { 
     int minDiff = newmin - min; 
     int maxDiff = newmax - max; 

     System.out.println("minDiff: " + minDiff + ", maxDiff: " + maxDiff); 

     int[] newdata = new int[newmax - newmin + 1]; 

     if ((newmax - newmin) > (max - min)) { 
      System.arraycopy(data, 0, newdata, maxDiff, max - min + 1); 
     } else if ((newmax - newmin) < (max - min)) { 
      System.arraycopy(data, minDiff, newdata, 0, newmax - newmin + 1); 
     } else { 
      // ... 
     } 

     return newdata; 
    } 

편집 : 나는 다음 코드를 사용하여 작업있어했지만, 작은 코드를 만들기 위해 할 수있는 하위 케이스 사이에 병합 개선이있다? 나는 그들 모습을 좋아하지 않는다. 또한 Object []를 사용하고 있지만 Integer []에서 작동하지 않는 경우 테스트를 위해 int []로 되돌릴 수 있습니다.

public static final <T> T[] arrMod(T[] data, int min, int max, int newmin, int newmax) { 
    //System.out.println(
    // "arrMod(data=" + Arrays.toString(data) + ",min=" + min + ",max=" + max + 
    // ",newmin=" + newmin + ",newmax=" + newmax + ")" 
    //); 

    int minDiff = newmin - min; 
    int maxDiff = newmax - max; 

    //System.out.println("minDiff: " + minDiff + ", maxDiff: " + maxDiff); 

    @SuppressWarnings("unchecked") 
    T[] newdata = (T[])Array.newInstance(data.getClass().getComponentType(), newmax - newmin + 1); 
    System.out.println("newdata: " + newdata); 

    if ((maxDiff - minDiff) > 0) { 
     // grow 
     //System.out.println("expand: (maxDiff - minDiff) > 0"); 
     arraycopy(data, 0, newdata, -minDiff, max - min + 1); 
    } else if ((maxDiff - minDiff) < 0) { 
     // shrink 
     //System.out.println("shrink: (maxDiff - minDiff) < 0"); 
     arraycopy(data, minDiff, newdata, 0, newmax - newmin + 1); 
    } else { 
     // move 
     //System.out.println("same: (maxDiff - minDiff) == 0"); 
     if (min > newmin) {  
      arraycopy(data, 0, newdata, -minDiff, max - min + maxDiff + 1); 
     } else { 
      arraycopy(data, maxDiff, newdata, 0, max - min - maxDiff + 1); 
     } 
    } 

    return newdata; 
} 

편집 2 : 개량을 testcases :

import static org.junit.Assert.*; 
import java.util.Arrays; 
import org.junit.Test; 

public class Hmm { 

    @Test 
    public void shrinkTest1() { 
     System.out.println(); 
     System.out.println("======= SHRINK TEST 1 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -1, 2); 
     Integer[] exp = new Integer[] { 4, 5, 6, 7 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void shrinkTest2() { 
     System.out.println(); 
     System.out.println("======= SHRINK TEST 2 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, -5, 4, -1, 2); 
     Integer[] exp = new Integer[] { 5, 6, 7, 8 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void expandTest1() { 
     System.out.println(); 
     System.out.println("======= EXPAND TEST 1 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 4); 
     Integer[] exp = new Integer[] { null, 3, 4, 5, 6, 7, 8, null }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void expandTest2() { 
     System.out.println(); 
     System.out.println("======= EXPAND TEST 2 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 6); 
     Integer[] exp = new Integer[] { null, 3, 4, 5, 6, 7, 8, null, null, null }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void sameTest1() { 
     System.out.println(); 
     System.out.println("======= SAME TEST 1 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -3, 2); 
     Integer[] exp = new Integer[] { null, 3, 4, 5, 6, 7 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void sameTest2() { 
     System.out.println(); 
     System.out.println("======= SAME TEST 2 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -1, 4); 
     Integer[] exp = new Integer[] { 4, 5, 6, 7, 8, null }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

    @Test 
    public void sameTest3() { 
     System.out.println(); 
     System.out.println("======= SAME TEST 3 ========"); 
     Integer[] res = WFMap.arrMod(new Integer[] { 3, 4, 5, 6, 7, 8 }, -2, 3, -4, 1); 
     Integer[] exp = new Integer[] { null, null, 3, 4, 5, 6 }; 
     assertArrayEquals("Array " + Arrays.toString(res) + " not equal to expected " + Arrays.toString(exp), exp, res); 
    } 

답변

1

다음 라인

if ((newmax - newmin) > (max - min)) { 
    System.arraycopy(data, 0, newdata, maxDiff, max - min + 1); 
} 

는 그것이 min 값에 의해 수행되어야하는 동안 대상 목적지는 max 값을 이용하여 결정되는 것을 나타 (시작 인덱스는 항상 min입니다).

두 가지 경우를 고려해야합니다. 새로운 최소값이 이전 값보다 작 으면 처음부터 데이터를 복사하고 어느 정도 오른쪽으로 옮깁니다. 그렇지 않으면 시작 부분에서 값을 삭제해야합니다. 즉, 0보다 큰 인덱스에서 복사하십시오.

if (minDiff < 0) { 
    System.arraycopy(data, 0, newdata, -minDiff, max - min + 1); 
} else { 
    System.arraycopy(data, minDiff, newdata, 0, max - min + 1); 
} 

이 코드 (예를 들어 minDiff의 큰 값을 원본/대상 배열 범위에서 실행될 수 있습니다) 귀하의 사용 사례에 따라 오버 플로우에 좀 더 검사를해야 할 수도 있습니다.

+0

안녕하세요, 도움 주셔서 감사합니다. 귀하의 확대 코드는 모든 경우에 작동했지만 코드 축소가되지 않았으며 크기 변경이없는 이동 코드를 추측하는 것은 조금 까다 롭습니다 (단, 가장 쉬운 경우는 .. 이상한). 그러나 최적화에 대한 아이디어가 있습니까? –

+0

[System.arraycopy javadoc] (http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang. 개체, % 20int, % 20int % 29) –

관련 문제