用数组A中缺少数组B的元素填充一个新数组 - Java

时间:2018-01-24 02:12:14

标签: java arrays

所以,基本上我有两个数组:

int[] listA = {2, -5, -121, 102, -35, -2, 0, -125, 802, -10};
int[] listB = {6, 99, -1, 12, 1, -2};

我想填写一个新数组(listDlistA中遗失的listB的所有元素。

输出应该是这样的:

输出:2,-5,-121,102,-35,0,-125,802,-10

我的代码如下:

int arraySize = 0; //Variable to determine size of the new array;
int difElements = 0; //Variable to count every different element;

for(int i = 0; i < listA.length; i++){
    for(int j = 0; j < listB.length; j++){
        if(listA[i] != listB[j]){
            difElements++;
        }
        if(difElements == listB.length){
        arraySize++;
    }

    }
     difElements = 0;
}
System.out.println("Size of the array with different elements : " + arraySize);

int[] listD = new int [arraySize]; //Declaring array with specified size;

然后我使用以下for循环来运行两个数组并检查是否有重复的元素:

for (int i = 0; i < listA.length; i++) {
    for (int j = 0; j < listB.length; j++) {
        if (listA[i] != listB[j]) {
            listD[i] = listA[i];
        } else {
            listD[i] = listA[i + 1];
        }
    }
}

我知道循环有什么问题,使用Debugger很容易看出它出错的地方,但此时我只是在圈中运行并编码相同的错误...循环后找到重复的元素我无法找到一种方法来规范化条件(listD[i] = listA[i]),因为它已经跳过了一个位置。也许我需要另一个循环来迭代通过listD但我从来没有嵌套过三个循环......

请记住这是非常基本的java编程,这些只是我班级的练习,以获得java编程的基础知识。我不知道任何POO,类,方法等,当然也不能应用它们。

7 个答案:

答案 0 :(得分:2)

我建议您使用一个临时数组(比如listC)来存储我们需要复制的元素的位置。

首次迭代两个数组,如果元素是唯一的,则计算新数组设置标志的大小。

然后,您遍历listC并复制listA

中的唯一元素
int[] listA = {2, -5, -121, 102, -35, -2, 0, -125, 802, -10, 7, 555};
int[] listB = {6, 99, -1, 12, 1, -2, 7, 555};

// array of flags indicating which elements of listA to copy
int[] listC = new int[listA.length];

// counter of unique elements from listA
int counter = 0;

for (int i = 0; i < listA.length; i++) {
    boolean contains = false;
    //simplified form of for loop if you don't use an index
    for (int b: listB) {
        if (listA[i] == b) {
            contains = true;
            break;
        }
    }
    if (!contains) {
        counter++;
        //setting listC[i] to 1 if listA[i] is not present in listB
        listC[i] = 1;
    }
}

// declaring array with specified size 
int[] listD = new int[counter];

counter = 0;

// iterating through the array of flags to copy unique elements
for (int i = 0; i < listC.length; i++) {
    if (listC[i] == 1) {
        listD[counter++] = listA[i];
    }
}

System.out.println(Arrays.toString(listD));

答案 1 :(得分:1)

如果你使用java 8,你可以使用它。

List<Integer> aList = Arrays.stream(listA).boxed().collect(Collectors.toList());
List<Integer> bList = Arrays.stream(listB).boxed().collect(Collectors.toList());

aList.removeIf(o -> bList.contains(o));

答案 2 :(得分:1)

您可以使用boolean类型的标记来识别

  1. listA中的元素,而不是listB中的元素。
  2. 未找到重复添加到新列表。
  3. 现在,代码以三个arrays一个listAlistBlistC开头。 listC的大小只能与listA相同,因为这是最大值(最差情况是listA的元素与listB不匹配)。另外我正在添加我的标记

    int[] listA = {2, -5, -121, 102, -35, -2, 0, -125, 802, -10, 0, 2};
    int[] listB = {6, 99, -1, 12, 1, -2};
    int[] listC = new int[listA.length];
    boolean elementFound = true;
    boolean duplicateFound = false;
    int thirdArrayIndex = 0;
    int zeroCount = 0;
    

    我们稍后会来标记elementFoundduplicateFound。首先,我们将进行基本的嵌套迭代

    for(int i=0; i< listA.length; i++) {
        boolean elementFound = true;
        for(int j=0; j< listB.length; j++) {
    

    要求listBlistA的每个元素进行迭代。现在在listB的循环中,我们保留了一个代码,用于检查元素的相似性并设置唯一元素标记。

    if(listA[i] == listB[j]) {
        elementFound = false;
        break;
    }
    

    如果listA中的元素与listB匹配,则将elementFound保持为false并打破内循环,因为无需再次搜索。这将执行到外部循环,我们将检查是否elementFound。如果是,那么只进行添加元素。

    添加部分将是这样的

    if(elementFound) {
        boolean duplicateFound = false;
        for(int k=0; k< listC.length; k++) {
            if((listA[i] == listC[k]) || (listA[i] == 0 && ++zeroCount > 1)) {
                duplicateFound = true;
                break;
            }
         }
         if(!duplicateFound) {
             listC[thirdArrayIndex++] = listA[i];
         }
    }
    

    在下一个for循环开始之前,我们会将duplicateFound保留为false。在for循环中,我们将检查两个条件

    1. listA中是否已存在listC中的元素。
    2. 初始listC将使用0初始化所有元素。因此,即使listA的元素为0listB中不存在,也不会将其添加到listC,因为0已经存在根据条件-1。
    3. 这就是条件类似于if((listA[i] == listC[k]) || (listA[i] == 0 && ++zeroCount > 1))的原因。最初zeroCount的值为0,因此当0中的listA不在listB

      listA[i] == 0 --> true &&
      ++zeroCount(value = 1) >= 2 --> false
      

      因此,0中的第一个listA将被添加。在k的for循环结束或breaked之后,我们将检查duplicateFound的条件,即listC中没有重复,如果这是真的go和add元素listAlistC

      listC[thirdArrayIndex++] = listA[i]; // listC[0] = listA[i]; first time
      

      只有在执行此行后,thirdArrayIndex的值才会增加,请参阅How do the post increment (i++) and pre increment (++i) operators work in Java?

      现在,当i的for循环完成时,listA中与listB不匹配的所有元素都会添加到listC,但如果找到匹配的元素并非全部listA元素将添加到listC,因此其他listC元素的值为0。这就是为什么我们将使用第四个数组listD仅复制listC中添加的listA元素。

      这就是thirdArrayIndex具有重要意义的地方,到目前为止thirdArrayIndex表示从listA添加到listC的元素总数。所以代码的最后一部分就像

      int[] listD = new int[thirdArrayIndex];
      for(int i=0; i<listD.length; i++) {
          listD[i] = listC[i];
      }
      

      最后打印所有数组

      System.out.println(java.util.Arrays.toString(listA));
      System.out.println(java.util.Arrays.toString(listB));
      System.out.println(java.util.Arrays.toString(listC));
      System.out.println(java.util.Arrays.toString(listD));
      

      所以最终的计划就像

      int[] listA = {2, -5, -121, 102, -35, -2, 0, -125, 802, -10, 0, 2};
      int[] listB = {6, 99, -1, 12, 1, -2};
      int[] listC = new int[listA.length];                
      int thirdArrayIndex = 0;
      int zeroCount = 0;
      
      for(int i=0; i< listA.length; i++) {
          boolean elementFound = true;
          for(int j=0; j< listB.length; j++) {
              if(listA[i] == listB[j]) {
                  elementFound = false;
                  break;
              }
          }           
          if(elementFound) {
              boolean duplicateFound = false;
              for(int k=0; k< listC.length; k++) {
                  if((listA[i] == listC[k]) || (listA[i] == 0 && ++zeroCount > 1)) {
                      duplicateFound = true;
                      break;
                  }
              }
              if(!duplicateFound) {
                  listC[thirdArrayIndex++] = listA[i];
              }
          }
      }
      int[] listD = new int[thirdArrayIndex];
      for(int i=0; i<listD.length; i++) {
          listD[i] = listC[i];
      }
      System.out.println(java.util.Arrays.toString(listA));
      System.out.println(java.util.Arrays.toString(listB));
      System.out.println(java.util.Arrays.toString(listC));
      System.out.println(java.util.Arrays.toString(listD));
      

答案 3 :(得分:0)

您可以将listB的所有元素添加到HashSet hashSet中,然后遍历listA的每个元素,并使用hashSet.contains()检查该元素是否在hashSet中。如果返回false,则添加到listD。

答案 4 :(得分:0)

只需使用List

int[] listA = {2, -5, -121, 102, -35, -2, 0, -125, 802, -10};
int[] listB = {6, 99, -1, 12, 1, -2};

List<Integer> b = Arrays.stream(listB).boxed().collect(Collectors.toList());

List<Integer> d = new ArrayList<>();
for (int i: listA) {
    if (!b.contains(i)) {
        d.add(i);
    }
}

答案 5 :(得分:0)

如果您不想使用列表,最好维护一个boolean数组,以便listA的元素标记为listB和{{{}} 1}}在klistA之间没有提供相似的元素。因此,结果数组的大小为listB,您可以在此之后添加元素

listA.length-k

答案 6 :(得分:0)

让我给我5美分。

我同意,这个问题可以通过普通的Java或使用streams来解决。但我认为,你不考虑元素重复,这可能很重要。例如。 listA = 2,2,2listB = 2,2。所以我认为,缺少一个2,所以它应该在输出中。

我给你我的方法,它适用于这种情况和独特的元素。我不使用streams简单明了,但您可以使用streams将其最小化:

private static int[] missing(int[] listA, int[] listB) {
    Map<Integer, Integer> map = new LinkedHashMap<>();

    for (int val : listB)
        map.put(val, map.getOrDefault(val, 0) + 1);

    int total = 0;

    for (int val : listA) {
        int count = map.getOrDefault(val, 0) - 1;
        map.put(val, count);

        if (count < 0)
            total++;
    }

    int i = 0;
    int[] listD = new int[total];

    for (Map.Entry<Integer, Integer> entry : map.entrySet())
        if (entry.getValue() < 0)
            for (int j = entry.getValue(); j < 0; j++)
                listD[i++] = entry.getKey();

    return listD;
}