JAVA-比较两个数组并仅使用第一个中的唯一值创建一个新数组

时间:2018-09-22 20:38:40

标签: java arrays

我必须按照以下条件解决一项练习:

比较两个数组:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

仅使用第一个数组中的唯一值创建一个新的int[] a1 = {1, 3, 7, 8, 2, 7, 9, 11}; int[] a2 = {3, 8, 7, 5, 13, 5, 12}; array。结果应如下所示:int[]

注意:不允许我使用int[] result = {1,2,9,11};ArrayList类来解决此任务。

我正在使用以下代码,但是填充循环的逻辑不正确,因为它引发了超出范围的异常。

Arrays

我也很喜欢如何用一个循环(学习目的)解决这个问题。

4 个答案:

答案 0 :(得分:2)

我提供以下解决方案。

  1. 遍历第一个数组,找出 min max 的值。
  2. 创建长度为 max-min + 1 的临时数组(您可以使用 max + 1 作为长度,但是当您有值(例如从100k)。
  3. 遍历第一个数组并标记临时数组中的存在值。
  4. 遍历第二个数组,并取消标记临时数组中的存在值。
  5. 将所有标记值从临时数组放入结果数组。

代码:

public static int[] getUnique(int[] one, int[] two) {
    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;

    for (int i = 0; i < one.length; i++) {
        min = one[i] < min ? one[i] : min;
        max = one[i] > max ? one[i] : max;
    }

    int totalUnique = 0;
    boolean[] tmp = new boolean[max - min + 1];

    for (int i = 0; i < one.length; i++) {
        int offs = one[i] - min;
        totalUnique += tmp[offs] ? 0 : 1;
        tmp[offs] = true;
    }

    for (int i = 0; i < two.length; i++) {
        int offs = two[i] - min;

        if (offs < 0 || offs >= tmp.length)
            continue;
        if (tmp[offs])
            totalUnique--;
        tmp[offs] = false;
    }

    int[] res = new int[totalUnique];

    for (int i = 0, j = 0; i < tmp.length; i++)
        if (tmp[i])
            res[j++] = i + min;

    return res;
}

答案 1 :(得分:2)

出于学习目的,我们不会添加新工具。

让我们遵循您之前的思路,然后更正第二部分:

decimal

对此:

// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
    int count = 0;
    for (int j = 0; j < a2.length; j++) {
        if (a1[i] != a2[j]) {
            count++;
            if (count < 2) {
                result[i] = a1[i];
            }
        }
    }
}

我假设您实现的“计数”是为了防止将假阳性结果添加到结果数组中(这将过去)。当一个人确定一个数组是否包含dups时,他不进行“计数”,他只是简单地将第一个数字与第二个数组进行比较,方法是向下移动列表,然后如果他看到一个dup(a1 [i] == a2 [j]),他会说“哦,它不是唯一的”(唯一=假),然后停止循环(中断)。然后,他会将数字添加到第二个数组中(result [i] = a1 [i])。

因此,要尽可能地结合两个循环:

//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
    boolean unique = true;

    for (int j = 0; j < a2.length; j++) {
        if (a1[i] == a2[j]) {
            unique = false;
            break;
        }
    }

    if (unique == true) {
        result[position] = a1[i];
        position++;
    }
}

答案 2 :(得分:0)

使您的代码正常工作

如果您纠正第二个循环,您的代码将正常工作。查看我所做的修改:

//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
    for (int j = 0; j < a2.length; j++) {
        if (a1[i] == a2[j]) {
              result[counter] = a1[i];
              counter++;
        }
    }
}




我的操作方式

现在,这是我将如何创建这样的方法,而无需多次检查重复项。看下面:

public static int[] removeDups(int[] a1, int[] a2) {
    int[] result = null;
    int size = 0;

    OUTERMOST: for(int e1: a1) {
      for(int e2: a2) {
        if(e1 == e2)
          continue OUTERMOST;
      }

      int[] temp = new int[++size];
      if(result != null) {
        for(int i = 0; i < result.length; i++) {
          temp[i] = result[i];
        }
      }

      temp[temp.length - 1] = e1;
      result = temp;
    }

    return result;
}

它不会创建具有固定大小的result数组,而是会在每次找到新的重复项时创建具有适当大小的新数组。请注意,如果a1等于a2,它将返回 null

答案 3 :(得分:-2)

您可以使用另一种方法来查看列表中是否包含元素:

public static boolean contains(int element, int array[]) {
    for (int iterator : array) {
        if (element == iterator) {
            return true;
        }
    }
    return false;
}

您的main方法将迭代每个元素,并检查它是否包含在第二个元素中:

int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
   if (!contains(it, a2)) {
       uniqueElements[index] = it;
       index++;
    }
}