簡體   English   中英

將具有最小+最大索引的裁剪數組值賦予具有所需最小+最大索引的目標數組

[英]Crop array values with min+max index given into a target array with a desired min+max index

我一直遇到這個問題,所以我想我會問這里。 基本上,我需要使用給定的目標數組中的最小和最大索引來“裁剪”數組值,使用所需的最小和最大索引(最小和最大索引圍繞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);
    }

以下幾行

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

表示目標目的地是使用max確定的,而應該由min完成(起始索引始終為min )。

你必須考慮兩種情況。 如果新min小於舊min,則可以從start復制數據並將其稍微向右移動。 否則,您必須從開頭刪除一些值,即從大於零的索引復制。

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

請注意,根據您的使用情況,此代碼可能需要對溢出進行更多檢查(例如,對於較大的minDiff值,您可能會耗盡源/目標數組邊界)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM