我一直遇到这个问题,所以我想我会问这里。基本上,我需要使用给定的目标数组中的最小和最大索引来“裁剪”数组值,使用所需的最小和最大索引(最小和最大索引围绕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);
}
答案 0 :(得分:1)
以下行
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
的大值)。