为了账号安全,请及时绑定邮箱和手机立即绑定

JAVA - 比较两个数组并创建一个仅包含第一个数组的唯一值的新数组

JAVA - 比较两个数组并创建一个仅包含第一个数组的唯一值的新数组

拉丁的传说 2021-10-06 09:42:43
我必须按照以下标准解决一个练习:比较两个数组: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上课来解决此任务。我正在使用以下代码,但填充循环的逻辑不正确,因为它引发了越界异常。public static int[] removeDups(int[] a1, int[] a2) {    //count the number of duplicate values found in the first array    int dups = 0;    for (int i = 0; i < a1.length; i++) {        for (int j = 0; j < a2.length; j++) {            if (a1[i] == a2[j]) {                dups++;            }        }    }    //to find the size of the new array subtract the counter from the length of the first array    int size = a1.length - dups;    //create the size of the new array    int[] result = new int[size];    //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];                }            }        }    }    return result;}我也很想知道如何用一个循环来解决这个问题(学习目的)。
查看完整描述

4 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我提供以下解决方案。

  1. 迭代第一个数组,找出它的最小值最大值

  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;

}


查看完整回答
反对 回复 2021-10-06
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

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


让我们按照你之前的思路,修正第二部分:


// 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];

            }

        }

    }

}

对此:


//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++;

    }

}

我假设您实施的“计数”是为了防止误报添加到您的结果数组中(这会结束)。当一个人确定一个数组是否包含 dup 时,他不做“计数”,他只是通过沿着列表向下比较第一个数字和第二个数组,然后如果他看到一个 dup (a1[i] == a2[j]),他会说“哦,它不是唯一的”(unique = false)然后停止循环(break)。然后他会将数字添加到第二个数组中 (result[i] = a1[i])。


所以要尽可能地结合这两个循环:


// Create a temp Array to keep the data for the loop

int[] temp = new int[a1.length];


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) {

        temp[position] = a1[i];

        position++;

    }

}


// This part merely copies the temp array of the previous size into the proper sized smaller array

int[] result = new int[position];


for (int k = 0; k < result.length; k++) {

    result[k] = temp[k];

}


查看完整回答
反对 回复 2021-10-06
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

让你的代码工作


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


//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具有固定大小的数组,而是在每次发现新的重复项时创建一个具有适当大小的新数组。请注意,如果等于,则返回null。a1a2


查看完整回答
反对 回复 2021-10-06
?
Helenr

TA贡献1780条经验 获得超4个赞

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


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++;

    }

}


查看完整回答
反对 回复 2021-10-06
  • 4 回答
  • 0 关注
  • 171 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信