【问题标题】:How do I check if there are duplicate numbers in an array? [duplicate]如何检查数组中是否有重复的数字? [复制]
【发布时间】:2013-10-07 10:21:44
【问题描述】:

我必须找出数组中是否有重复的数字,如果发现重复我需要-5分。到目前为止,这是我的代码:

for (int k = 0; k < arrNums2.length; k++) 
{
    for (int i = 0; i < arrNums2.length; i++) 
    {
        if (arrNums2[k] == arrNumsCompare[i])
        {             
            points = points - 5;            
            for (int j = 0; j < arrNums2.length; j++)
            {
                if (arrNums2[k] == arrNums2[j])
                {
                    arrNums2[j] = 0;
                }
            }
        }
    }
}

【问题讨论】:

  • 您的具体问题是什么?
  • 排序这个数组,然后遍历它。如果邻居是平等的,你就有了一个重复。
  • @PradeepSimha - 我真的怀疑Set 是否可以在这种情况下使用。有一些与要完成的点相关的事情,以防发现重复。 Set 甚至不会让你知道它找到了重复项
  • 那是 NOT A DUPLICATE,他有问题,需要解决。我在那里看不到。如果他得到一个现成的解决方案,对于一个与他的问题不同的问题,他将不会学到任何东西,也不会从错误中吸取教训。
  • 你为什么要这么做arrNums2[j]=0;?它是您的要求还是您的逻辑的一部分?

标签: java arrays collections duplicates


【解决方案1】:

我建议这个单行解决方案:

Integer[] numbers = {1,2,3,4,5,6,5,4,3,2,1};

return 5 * (new HashSet<Integer>(Arrays.asList(numbers)).size() - numbers.length);

我将所有元素添加到一个集合中,根据定义它拒绝重复。然后我将集合的大小与数组的长度进行比较,并将结果乘以 5。

【讨论】:

  • +1,但您应该使用 HashSet 来提高速度
  • @MikeFHay 是的。我编辑了,谢谢。
  • +1 最优雅、最简单的答案。也有很好的解释。
【解决方案2】:

你可以处理这个伪代码:

int nDuplicates = 0;
arrNums2 = arrNums2.Sort(); // Sort the array in ascending or descending order. 

for(int i =1; i<arrNums2.size(); ++i)
{ 
 if(arrNums2[i-1] == arrNums2[i])
 {
  nDuplicates++;
 }
}
Point -= nDuplicates*5;

编辑:如果必须将输入 5,5,5,5 视为单个重复项,则使用以下 sn-p。

    int nDuplicates = 0;
    arrNums2 = arrNums2.Sort(); // Sort the array in ascending or descending order. 
    int DuplicateNumber = 0;
       for(int i =1; i<arrNums2.size(); ++i)
        { 
         if(arrNums2[i-1] == arrNums2[i])
         {
          if(DuplicateNumber != arrNums2[i])
          {
           nDuplicates++;
           DuplicateNumber = arrNums2[i];
          }
         }
        }
     Point -= nDuplicates*5;

【讨论】:

  • 哦,我似乎可以从这里开始工作,但唯一不起作用的问题是如果用户输入例如:5,5,5,5,5
  • 有什么问题?它将被视为 5 的 3 个副本。或者您希望它作为一个副本?
  • @JoshBoiskin - 我已经编辑了我的答案,以适应将 5,5,5,5 视为单个重复项的第二种可能性。
【解决方案3】:

要在不事先排序的情况下在原始数组的一次迭代中查找重复项,您可以使用 HashMap 来存储每个条目并在每次再次找到它时递增计数。
这样,您可以在找到第一个重复项后立即停止处理或继续查找所有...

编辑: http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

Hashmap entries  = new Hashmap<Integer, Integer>();
    for (int k = 0; k < arrNums2.length; k++) {
       if (!entries.containsKey(arrNums2[k])) {
         entries.put(arrNums2[k], 1);
       } else {
         // You already found the duplicate, so you can do whatever you like 
         Integer count = entries.get(arrNums2[k]);
         count = count + 1;
         entries.put(arrNums2[k], count);
       }
    }

【讨论】:

  • 你能给我一个这个HashMap的例子吗?
【解决方案4】:

这个循环似乎永远持续下去,直到达到负值限制。 看来您已经创建了临时数组arrNumsCompare 来实现逻辑。 给你:

   for (int k=0; k < arrNums2.length; k++) 
     {
       for (int i = 0; i < arrNums2.length; i++) 
       {
         if(i == k)
         {
           i++;
         } 
         if(arrNums2[k]==arrNums2[i])
         {             
            points = points -5;
            break;
         }
       }
     }

注意:如果一个值出现 3 次,则扣除额为 10,依此类推。如果您想扣除一次,则需要进一步工作。请问您是否可以这样做。

提示:您需要维护另一个已标记为重复的数字数组并添加另一个检查以跳过:)

【讨论】:

  • 是的,哦,我会努力的,因为如果发现重复,则不能再次计数
  • 如果一个值存在4次,只需要扣5分吗?
  • 是的,跳过那个索引更好吗?也许通过将其设置为 -1 ,然后仅在不 = -1 时检查插槽?
  • 不要改变你的阵列。我正在添加我上面的答案。等几分钟。
  • 关于您的代码的另一个问题? ,您检查是否 i =k 然后 i++ 的原因是什么?你不应该检查实际的数组而不是插槽号吗?
【解决方案5】:

第二版重复多次扣分一次

对于此解决方案,数组必须只包含正数。

for (int k=0; k < arrNums2.length; k++) 
     {
       if(arrNums2[k] == -1)
       {
         continue;
       }
       Boolean found = fasle;
       for (int i = k+1; i < arrNums2.length; i++) 
       {             
         if(arrNums2[k]==arrNums2[i])
         {  
            if(found == false)
            {            
               points = points -5;
               found = true;           
            }
            arrNums2[i] = -1;
         }
       }
     }

【讨论】:

    【解决方案6】:

    对于集合 {1,2,3,4,5,5,5,5,6,7,8,9,9,9,9} 点数为 100,以下代码将减少点数10.好像只有2个重复存在。希望这会有所帮助。

    private int[] numbers;
    private Set<Integer> previousDuplicates = new HashSet<Integer>();
    private int points;
    
    
    public void reducePointsForDuplicates(){
        for (int i = 0; i < numbers.length; i++) {
             reducePointsIfDuplicate(i, numbers[i]);
        }
    }
    
    private void reducePointsIfDuplicate(int position, int number){
        for (int i = position + 1; i < numbers.length; i++) {
            if(number == numbers[i]){ 
                reducePointsForNewDuplicate(number);
            }
        }
    }
    
    private void reducePointsForNewDuplicate(int number){
        if (!previousDuplicates.contains(number)){
            points = points - 5;
        }
        previousDuplicates.add(number);
    }
    
    
    
    public int[] getNumbers() {
        return numbers;
    }
    
    public void setNumbers(int[] numbers) {
        this.numbers = numbers;
    }
    
    public int getPoints() {
        return points;
    }
    
    public void setPoints(int points) {
        this.points = points;
    }
    

    【讨论】:

    • 它只适用于已排序的数组。
    • 我测试过了。无论数组是否排序,它都有效。
    • 知道了,我们已经测试过了,不需要在位置之前检查。
    • 设为for (int i = position+1 并从if(position != i &amp;&amp; number == numbers[i]) 中删除检查position != i &amp;&amp;
    • 已经按照建议编辑了代码,它确实使它更容易阅读,当然工作方式也一样。
    猜你喜欢
    • 1970-01-01
    • 2021-01-12
    • 2021-09-15
    • 1970-01-01
    • 2013-11-14
    • 2012-02-04
    • 2021-01-03
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多