0

我正在尝试编写一种方法来查找数组中的重复值,并在这种情况发生两次时返回 true(否则返回 false)。

我有一些东西,但由于某种原因,它在某些情况下无法正常工作:

public static boolean twoDuplicates(int[] values) {

    boolean twoDuplicate = false;
    int counter = 0;

    for(int i = 0; i < values.length; i++){
        for(int z = i + 1; z <= values.length - 1; z++){
            if(i != z && values[i] == values[z])
                counter++;
        }
    }
    if(counter == 2)
        twoDuplicate = true;
    return twoDuplicate;
}

现在,我测试了它,当值为 [3,3,3,6,6] 时它不起作用。有什么原因吗?

编辑:我忘了提到重复项必须是不同的。

4

6 回答 6

1

在您现有的代码中,您正在计算对的数量而不是查找重复项。您应该为每个“i”分别检查计数器。

public static boolean twoDuplicates(int[] values) {

boolean twoDuplicate = false;

for(int i = 0; i < values.length; i++){
int counter = 0;
for(int z = i + 1; z <= values.length - 1; z++){
        if(i != z && values[i] == values[z])
            counter++;
    }
   if(counter == 2) // or if(counter > 1) if finding three duplicates is also fine
      return true;
}

return false;
}

或者

public static boolean twoDuplicates(int[] values) 
{
    for(int i = 0; i < values.length; i++)
    {
       int counter = 0;
       for(int z = i + 1; z <= values.length - 1; z++)
       {
            if(values[i] == values[z])
            {
                counter++;
                if(counter == 2) // check here if you want 2 or more duplicates
                   return true;
            }
        }
        // check here if you want exactly two duplicates
    }

    return false;
}
于 2013-04-15T02:58:59.310 回答
1

看起来您只是在计算匹配的总数。即,您将匹配 3 两次(现在 counter = 3)和 z 一次,总共 4。当我使用数组运行此代码时,我得到 counter = 4;

我认为下面的代码将返回不同重复的数量(重复的数字,无论它发生多少次)。这将为测试数组返回 2。它首先对数组进行排序,然后查找重复项,忽略已经计算过的重复项。

public static boolean twoDuplicates(int[] values) {

        boolean twoDuplicate = false;
        int counter = 0;
        Arrays.sort(values);
        int old = values[0];
        boolean numberSeen = false;
        for(int i = 0; i < values.length; i++){
            if(values[i] == old){
                if(!numberSeen){
                    counter++;
                    numberSeen = true;
                }
            }else{
                numberSeen = false;
                old = values[i];
            }
        }
        if(counter == 2)
            twoDuplicate = true;
        return twoDuplicate;
    }
于 2013-04-15T02:49:26.527 回答
0

根据你的逻辑,如果你有超过2个重复,函数会返回false,也许你应该用“counter>1”来判断,计数器定义应该放在外部迭代中。而且我认为算法不够聪明。

于 2013-04-15T02:48:14.013 回答
0

1. 您需要记住找到的第一个重复对的值。

否则,连续 3,3,3 - 你会发现 3 两次。所以存储第一个重复值并比较这不是它。

int firstDuplicate;


if(i != z && values[i] == values[z]) {

     if (counter == 0) {

          counter++;
          firstDuplicate = values[i];

     } else if (counter == 1 && values[i] != firstDuplicate) {

          counter++;
     }
}

2. z <= values.length - 1应该是z < values.length。正如你在第一个for.

3. { }即使块是单行的,也始终使用。

UPD

4. break;当你找到你需要的东西时,使用它来停止迭代。

for(){
    for(){

    }
    if(counter == 2) {
        twoDuplicate = true;
        break;
    }
}

或更好

for(int i = 0; i < values.length && counter < 2; i++;){
    for(){

    }
}

return counter >= 2;
于 2013-04-15T02:54:59.877 回答
0

情况是这样的:

第一个循环读取第一个 3。第二个循环读取第二个和第三个 3。计数器变为 2。第一个循环读取第二个 3。第二个循环读取第三个 3。计数器变为 3。第一个循环读取第三个 3。第二个循环找不到任何东西。计数器为 3。第一个循环读取第一个 6。第二个循环读取第二个 6。计数器为 4。第一个循环读取第二个 6。第二个循环找不到任何东西。计数器为 4。

你需要做的是把它放在if( counter == 2 )第二个循环之后。这将解决您的问题。

if( counter == 2 ) return true;

于 2013-04-15T02:53:29.083 回答
0

这就是我只需一个循环就可以做到的方式

    public static boolean twoDuplicates(int[] values) {
    HashSet<Integer> map = new HashSet<Integer>();
    int cont = 0;
    for (int i = 0; i < values.length; i++) {
        if (map.contains(values[i])){
            cont++;
            if (cont == 2) 
                return true;
        }           
        else
            map.add(values[i]);

    }
    return false;
}
于 2013-04-15T03:13:37.177 回答