我正在尝试学习一些算法,并且想使用Set删除重复项。我正在使用我的小型算法合并两个排序的数组,该算法检查数组A中的数字是否小于C中存储的B,然后再添加剩余的数组
我已经尝试过,但是一直感到困惑
//arrays must be sorted
int a [] = {1,3,4,5};
int b [] = {5,6,8,9,10};
System.out.println(Arrays.toString(combineArray(a,b,3,4)));
}
private static int[] combineArray(int[] A, int[] B, int m, int n) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
int k = 0;
int c [] = new int[9];
while(i <= m && j <= n) {
if(A[i] < B[j]) {
c[k++] = A[i++];
}else {
c[k++] = B[j++];
}
}
for(; i <=m; i++) {
c[k++] = A[i];
}
for(; j <=n ; j++) {
c[k++] = B[j];
}
return c;
}
没有错误只是想要一些帮助删除重复项。
答案 0 :(得分:0)
您不需要使用自己的算法,Java 8+可以很好地做到这一点:
int[] array1 = {1, 2, 65, 4, 8, 5, 7, 18, 6, 0};
int[] array2 = {0, 2, 11, 12, 5, 6, 8};
int[] merged = IntStream.concat(IntStream.of(array1), IntStream.of(array2))
.distinct()
.sorted()
.toArray();
修改
在distinct()
之后调用sorted()
似乎更快。
看这里:
Java Streams: How to do an efficient "distinct and sort"?
所以最好这样做:
int[] array1 = {1, 2, 65, 4, 8, 5, 7, 18, 6, 0};
int[] array2 = {0, 2, 11, 12, 5, 6, 8};
int[] merged = IntStream.concat(IntStream.of(array1), IntStream.of(array2))
.sorted()
.distinct()
.toArray();
To your posted algorithm:
我已将您的程序调试为以下状态:
i=3, j=0 k=3.
The output of c is then: 1,3,4,0...
在此步骤中,您进行了以下比较:A[3] < B[0]
,即5<5
和false
,因此进入了else
。在那里,添加了5
中的B[]
。
在下一步中,我们得到了i=3 (nothing changed because the first if was not entered!), j=1 and k=4
,因此我们要检查:A[3] < B[1]
的值为true
,因为5<6
,所以A[i++]
将被添加,是A[4]
,即5
。这就是加倍的五个数字的来源。现在如何解决这个问题?
我希望您很清楚,if语句是您要检查较小或等于的问题,这实际上意味着“允许”输入条件两次:一次是第一个操作数为小于第二个和第二个相等的时间。由于在两个数组的if语句中都有这种情况,因此将有重复项。仅允许一个if条件检查较小或相等。因此,如果您更改代码:
私有静态int [] CombineArray(int [] A,int [] B,int m,int n){
int i = 0;
int j = 0;
int k = 0;
int c[] = new int[9];
while (i < m && j < n) {
if (A[i] < B[j]) {
c[k++] = A[i++];
} else {
c[k++] = B[j++];
}
}
for (; i < m; i++) {
c[k++] = A[i];
}
for (; j <= n; j++) {
c[k++] = B[j];
}
return c;
}
它不会输入两次,也不会添加重复的数字两次。对于您的示例,输出为:
[1, 3, 4, 5, 6, 8, 9, 10, 0]
由于删除了重复项,因此会有一个0
。