2011-11-26 39 views
3

我一直有這個問題一段時間,所以我想我會在這裏問。基本上,我需要用最小和最大索引給某個目標數組「裁剪」數組值,並使用所需的最小和最大索引(最小和最大索引圍繞0),並且數組大小尊重最小值和最大值之間的差異。當然,實際數組從索引0開始,但實際數據的偏移量可能不同。使用最小+最大索引將數組值賦給具有期望的最小+最大索引的目標數組

我已經去了(見下文),但我有一些困難。我的數學真的很差。該代碼被安排爲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:改進的測試用例:

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); 
} 

指示目標目的地使用max值來確定,而應該由min值來實現(起始索引總是min)。

你必須考慮兩種情況。如果新分鐘比舊分鐘小,您可以從開始複製數據並將其稍微向右移動。否則,你必須從一開始就刪除一些值,即從大於零的索引拷貝。

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) –