【问题标题】:How to find and write down repeated elements in an array? [duplicate]如何查找和写下数组中的重复元素? [复制]
【发布时间】:2015-12-14 13:29:55
【问题描述】:
public class Pascal {

    public static void main(String[] args){
    int array[] = {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13};


    for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (i == j){
                    System.out.println(i);
                } else {
                    System.out.println("Nothing");
                }
            }
        }
    }
}

它不能正常工作。我尝试使用foreach 循环,但效果不佳。我认为它几乎完成了,我错过了一些微不足道的东西。

【问题讨论】:

  • 如果你错过了什么是微不足道的,它不会破坏你的代码:)

标签: java


【解决方案1】:

您的问题

  • 您正在比较 i 而不是 array[i]
  • 您正在解析 数组两次,因此每个值至少显示一次,即使 它不是重复的。

这会起作用,但它仍然会打印多次重复值:

int array[] = {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13,13};

for (int i = 0; i < array.length; i++) {
  for (int j = 0; j < array.length; j++) {
    if (array[i] == array[j] && i != j){
      System.out.println(array[i]);
    }
  }
}

现在,我向您展示解决此问题的不同样式。

命令式风格的更好解决方案。

您正在解析数组n 次,这是无用的。如果数组已排序(无论如何都可以排序),您可以像在此解决方案中一样将一个元素与下一个元素进行比较:

int array[] = {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13};

//Optionally
Arrays.sort(array);

Integer last = null;
for(int i = 0; i < array.length -1 ; i++) {
  if(array[i] == array[i+1] && (last == null || !last.equals(array[i]))) {
    System.out.println(array[i]);
    last = array[i];
  }
}

我认为这是最有效的解决方案,但不是最易读的。

使用 foreach 循环的另一种解决方案

除非您明确需要访问当前元素的索引,否则使用普通的旧 for 循环是邪恶的,因为它引入了不必要的变量 i,这会污染代码的可读性。

您可以更喜欢使用 foreach 语句:

int array[] = {1,2,3,3,3,4,5,6,6,7,8,8,10,10,11,12,13,13};

Set<Integer> uniqueValues = new HashSet<>();
Set<Integer> alreadyDisplayed = new HashSet<>();
for(Integer value : array) {
  if(uniqueValues.contains(value) && !alreadyDisplayed.contains(value)) {
    System.out.println(value);
    alreadyDisplayed.add(value);
  }
  uniqueValues.add(value);
}

功能风格的更好解决方案

这个对Java8更友好的解决方案:

int array[] = {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13};

//Count occurrences of each number
Map<Integer, Integer> map = new HashMap<>();
Arrays.stream(array).forEach(value -> {
  Integer occurrences = map.get(value);
  map.put(value, occurrences == null ? 1 : occurrences +1);
});

//Display number of occurrences when nbOccurrences > 1
map.entrySet()
    .stream()
    .filter(entry -> entry.getValue() > 1)
    .forEach(entry -> System.out.println(entry.getKey() + " : "+entry.getValue()));

请注意,它还给出了每个值的出现次数。如果您不需要它们,您可以像以前的解决方案一样缩短代码。

逻辑风格的更有趣的解决方案。

Integer array[] = {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13};

//Convert the array to a list.
List<Integer> list = Arrays.stream(array).collect(Collectors.toList());

//Use a Set in order to build the collection of unique values.
Set<Integer> uniqueValues = new HashSet<>(list);

//Remove each unique value once from the original list.
uniqueValues.stream().forEach(list::remove);

//Re-compute unique values of the resulting list and display them.
new HashSet<>(list).forEach(System.out::println);

【讨论】:

    【解决方案2】:

    将“if (i == j)”替换为“if (array[i] == array[j])”

    【讨论】:

    • 不仅是他不应该将我的意思相同的元素与当前索引进行比较。
    【解决方案3】:
    • 首先,您应该比较 array[i] 和 array[j],而不是 i 和 j。

    • 其次,如果 i == j,则不应将元素与其自身进行比较。

    例如:

    for (int i = 0; i < array.length; i++) {
        for (int j = i + 1; j < array.length; j++) {
            if (array[i] == array[j]) {
                System.out.println(array[i]);
            }
        }
    }
    

    这将打印重复的值。

    【讨论】:

      【解决方案4】:

      您应该比较数组中的元素,而不是数组索引。此外,当索引相同时,数字不会重复,只是相同的数字。

      for (int i = 0; i < array.length; i++) {
          for (int j = 0; j < array.length; j++) {
              if ((array[i] == array[j]) && (i != j)) {
                  System.out.println(array[i]);
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        如果您想使用更多空间来创建Set 对象

        Set<Integer> set = new HashSet<Integer>;
        for (int i = 0; i < array.length; i++) {
            boolean wasAdded = set.add(i);
            if(!wasAdded){
            System.out.println(array[i]);
            }
        }
        

        【讨论】:

        • 为什么不使用 Java 7 的 foreach?不必手动管理i。顺便说一句,我认为它在代码中引入了一个错误,因为你需要做set.add(array[i]),而不是set.add(i)
        • 好吧,我已经从问题中复制了那行。
        【解决方案6】:

        你正在使用蛮横的方法来做到这一点。

        for (int i = 0; i < array.length; i++) {
                for (int j = i+1; j < array.length; j++) {
                    if (array[i] == array[j]){
                        System.out.println(i);
                    } else {
                        System.out.println("Nothing");
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案7】:

          另一种可能性是使用Map 准确计算所有条目:

          public class Pascal {
          
            public static void main(String[] args) {
              int array[] = { 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 10, 10, 11, 12, 13 };
          
              Map<Integer, Integer> lAllDoubleEntries = new HashMap<Integer, Integer>();
          
              for (int i = 0; i < array.length; i++) {
                Integer count = lAllDoubleEntries.get(array[i]);
                if (null == count) {
                  lAllDoubleEntries.put(array[i], 1);
                } else {
                  lAllDoubleEntries.put(array[i], ++count);
                }
              }
              for (int lKey : lAllDoubleEntries.keySet()) {
               if (lAllDoubleEntries.get(lKey)>1) {
                 System.out.println("Value "+lKey+" exists in list "+lAllDoubleEntries.get(lKey)+" times");
               }
              }
          
            }
          }
          

          输出:

          值 3 在列表中存在 2 次​​p>

          值 6 在列表中存在 2 次​​p>

          值 8 在列表中存在 2 次​​p>

          值 10 在列表中存在 2 次​​p>

          【讨论】:

          • 如果您想使用MapInteger 映射到Object,请考虑使用SparseArray 来提高性能。
          【解决方案8】:

          使用 Set 的解决方案。

          不包含重复元素的集合。更正式地说,集合不包含满足 e1.equals(e2) 的元素 e1 和 e2 对,并且最多包含一个空元素。

              int[] myArr =  {1,2,3,3,4,5,6,6,7,8,8,10,10,11,12,13};
              Set<Integer> mySet = new HashSet<>();
          
              for (int i = 0; i < myArr.length; i++) {
                  if (!mySet.add(myArr[i])) {
                      System.out.println(myArr[i]);
                  }
              }
          

          【讨论】:

            【解决方案9】:

            算法解释duplicate-entries-with-4kb-constraint-bit-array-is-the-solution
            公共静态无效主要(字符串参数[]){ int input[] = new int[ /* 选择一个尺寸 / ]; input[0] = / 填充数组 */ int[] isDuplicate = new int[32000 >> 5]; // 除以 32 int wordNumber, 掩码;

                for(int i = 0; i < input.length; i++ ){
                        mask = 1 << (input[i]%32);
                        wordNumber = input[i]/32;
                        if((mask & isDuplicate[wordNumber]) != 0){
                                System.out.println(input[i]);
                        }else{
                                isDuplicate[wordNumber] |= mask;
                        }
                    }
               }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-08-21
              • 1970-01-01
              • 2011-06-06
              • 2017-08-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多