我已经尝试过很多次来修复方法void sameNumbers()
中的失败,但仍然没有找到解决方案。
Junit失败: junit output
问题是,当第一个数组为[1]
而第二个数组为[0, 1]
时,它将返回true
,而不是false
。
有人可以解释并帮助我解决此问题吗?
谢谢。
public class SameNumbers {
public static boolean sameNumbers(int[] values1, int[] values2) {
Arrays.sort(values1);
Arrays.sort(values2);
boolean found = false;
if (values1.length == 0 && values2.length == 0) {
found = true;
} else if (values1.length == 0 && values2.length > 0 || values1.length > 0 && values2.length == 0) {
found = false;
} else if (Arrays.equals(values1, values2)) {
found = true;
} else if (values1.length > 0 && values2.length > 1 || values1.length > 1 && values2.length > 0) {
for (int i = 0; i < values1.length; i++) {
for (int k = 0; k < values2.length; k++) {
if (values1[i] == values2[k]) {
found = true;
} else {
found = false;
}
}
}
}
return found;
}
}
class SameNumbersTest {
static final int nbrTests = 20;
private Random random = new Random();
@Test
void sameNumbers1() {
Assertions.assertEquals(true, SameNumbers.sameNumbers(new int[] {}, new int[] {}),
"SameNumbers.sameNumbers(new int[]{}, new int[]{})");
}
@Test
void sameNumbers2() {
for (int i = 0; i < nbrTests; i++) {
int r = random.nextInt(20);
Assertions.assertFalse(SameNumbers.sameNumbers(new int[] {}, new int[] { r }),
"SameNumbers.sameNumbers(new int[]{}, new int[]{r})");
Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { r }, new int[] {}),
"SameNumbers.sameNumbers(new int[]{r}, new int[]{})");
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { r }, new int[] { r }),
"SameNumbers.sameNumbers(new int[]{r}, new int[]{r})");
}
}
@Test
void sameNumbers3() {
for (int i = 0; i < nbrTests; i++) {
int r = random.nextInt(20);
if (r != 1) {
Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }),
"SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})");
Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }),
"SameNumbers.sameNumbers(new int[]{r, 1}, new " + "int[]{1})");
} else {
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }),
"SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})");
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }),
"SameNumbers.sameNumbers(new int[]{r, 1}, new int[]{1})");
}
}
}
@Test
void sameNumbers4() {
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 2, 1 }),
"SameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 2, 1})");
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 3, 2, 1 }),
"SameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 3, 2, 1})");
Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 4, 2, 1 }),
"ameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 4, 2, 1})");
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2 }, new int[] { 2, 1, 1 }),
"SameNumbers.sameNumbers(new int[]{1, 2}, new int[]{2, 1, 1})");
Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 2 }, new int[] { 2, 1, 1 }),
"SameNumbers.sameNumbers(new int[]{1, 2, 2}, new int[]{2, 1, 1})");
}
}
答案 0 :(得分:2)
在for循环中,它检查[0]并将其等于false,但是一旦将其设置为false,就不会中断for循环,因此它会检查[1]并以found = true结尾
答案 1 :(得分:2)
这些循环无法在found中添加有意义的值。
for (int i = 0; i < values1.length; i++) {
for (int k = 0; k < values2.length; k++) {
if (values1[i] == values2[k]) {
found = true;
} else {
found = false;
}
}
}
可以写为
found = values1[values1.length - 1] == values2[values2.length - 1];
您打算进行如下操作,以检查values1是values2的子集。
WRONG:
found = true;
for (int i = 0; i < values1.length; i++) {
found = false;
for (int k = 0; k < values2.length; k++) {
if (values1[i] == values2[k]) {
found = true;
break;
}
}
if (!found) {
break;
}
}
当您对一个更好的算法进行排序时,将是:
public static boolean sameNumbers(int[] values1, int[] values2) {
values1 = IntStream.of(values1).sorted().distinct().toArray();
values2 = IntStream.of(values2).sorted().distinct().toArray();
if (values1.length != values2.length) {
return false;
}
for (int i = 0; i < values1.length; ++i) {
if (values1[i] != values2[i]) {
return false;
}
}
return true;
}
或
public static boolean sameNumbers(int[] values1, int[] values2) {
Arrays.sort(values1);
Arrays.sort(values2);
int i1 = 0;
int i2 = 0;
while (i1 < values1.length && i2 < values2.length) {
if (values1[i1++] != values2[i2++]) {
return false;
}
while (values1[i1] == values1[i1 - 1] { // Repetitions in values1
++i1;
}
while (values1[i2] == values1[i2 - 1] { // Repetitions in values1
++i2;
}
}
return i1 == values1.length && i2 == values2.length;
}
或
public static boolean sameNumbers(int[] values1, int[] values2) {
values1 = IntStream.of(values1).sorted().distinct().toArray();
values2 = IntStream.of(values2).sorted().distinct().toArray();
return Arrays.equals(values1, values2);
}
测试失败时,测试可能是错误的。
答案 2 :(得分:1)
对数组values1
和values2
进行排序后,可以使用Arrays的equals
函数(就像您已经做过的那样):
Arrays.sort(values1);
Arrays.sort(values2);
return Arrays.equals(values1, values2)
此函数已经检查所有条目和两个数组的长度是否相同。 这样您就可以直接返回结果。 您不需要做更多的事情。
编辑:
您发表评论后:我错过了限制。
您可以先用一组集合消除数组values1
和values2
中的重复项:
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>(Arrays.asList(values));
Integer[] valuesWithoutDuplicates = linkedHashSet.toArray(new Integer[] {});
在集合中,每个值都是唯一的。通过将数组[1,2,3,3,4,5,5]从数组转换为集合,可以将其简化为[1,2,3,4,5]。转换回数组,将使您可以处理具有唯一元素的数组。
例如,如果您有两个数组[1,2,2,3]和[1,2,3,3,3]都将简化为[1,2,3]并相等。
答案 3 :(得分:1)
If you pass the value between 0-20 it will return true as your fourth condition is getting satisfied. So, intead of changing your if conditions you can put an interger value which greater that 20.
public void sameNumbers3() {
for (int i = 0; i < nbrTests; i++) {
int r = random.nextInt(20);
if (r != 1) {
Assert.assertFalse("SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})",
SameNumbers.sameNumbers(new int[] { 21 }, new int[] { r, 1 }));
Assert.assertFalse("SameNumbers.sameNumbers(new int[]{r, 1}, new " + "int[]{1})"
,SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 21 }));
} else {
Assert.assertTrue("SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})",
SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }));
Assert.assertTrue("SameNumbers.sameNumbers(new int[]{r, 1}, new int[]{1})",
SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }));
}
}
}