Java-列出int数组中重复值的索引

3

我需要定位并列出数组中所有重复的索引值。

例如: int[] array = { 0, 7, 9, 1, 5, 8, 7, 4, 7, 3};

数字7在索引1、6和8处出现了三次。如何修改现有代码,以便使outputResults.setText()显示重复值的位置?如果有帮助,outputResults.setText()是JTextField。

String tmp1 = getNumbers.getText();
    try {
        int search = Integer.parseInt(tmp1);
        for (p = 0; p < array.length; p++) {
            if(array[p]==search) {
                b = true;
                index = p;
            }
        }   
        if(b==true)
            outputResults.setText(search + " was in the following fields of the array " + index);
         else 
            throw new NumberNotFoundException("Your number was not found.");


    } catch (NumberFormatException ex) {
        JOptionPane.showMessageDialog(getContentPane(), "You can only search for integers.");

    } catch (NumberNotFoundException ex) {
        JOptionPane.showMessageDialog(getContentPane(), ex.getMessage());
    }

在目前的状态下,它只会列出重复数字最后一次被定位的位置,根据我的示例是索引8。数组中的数字列表由用户输入,并且我不允许对这些值进行排序。我的最初想法是创建一个嵌套循环,每当它找到一个重复的数字时,就将p(当前正在搜索的索引)添加到一个新数组中。然后,我会在outputResults.setText()中列出完整的数组,但是当我尝试时,它给出了多个警告和错误。
如果需要,可以在此处找到完整代码:http://pastebin.com/R7rfWAv0 是的,完整程序很乱,但它完成了工作,我头疼了好久才完成它。还请注意,在完整程序中,教授要求我们如果检测到重复值,则抛出异常以获取额外学分。我已经做到了,但我注释掉了它以完成原始任务,请忽略它。

如果你稍微想一下,我相信答案是相当明显的。在我看来,这就是作业的目的。也许你可以在那里做些其他的事情,而不是保存索引... - Morfic
说实话,我也是这么想的,但是在盯着一个任务几个小时后,你往往会忘记基础知识。我已经在上面工作了相当长时间,但似乎无法使其正常工作。我的主要问题是在单行的JTextField中显示索引数组。 - user1462300
5个回答

1

我认为你应该使用一个List来记录索引。

List<Integer> indexs =new ArrayList<Integer>();
for (p = 0; p < array.length; p++) {
    if(array[p]==search) {
        indexs.add(p);
    }
}
if(p.length()>0){
    //print the result
}

我们在课堂上还没有讲解过List,但是在阅读了Oracle的相关资料后,它似乎可以完成工作。唯一的问题是Eclipse告诉我:“类型List不是泛型;不能使用<整数>参数进行参数化”。我会进一步研究它,感谢您的提示! - user1462300
@user1462300 只需使用<Integer>即可,<Integers>是无效的。请参阅http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf获取更多详细信息。 - plucury

1

不需要哈希表、列表或其他什么,你可以很容易地这样做:

int [] array = { 0, 7, 9, 1, 5, 8, 7, 4, 7, 3};
int pointer=0;
int currNumber;
while(pointer<array.length)
{   
  currNumber=array[pointer];
  for(int i=0;i<array.length;i++){          
    if(currNumber==array[i] && i>pointer){
        System.out.println("Duplicate for "+currNumber +" in " +i);
        break;
    }
  }   
  pointer++;
}

它将打印数组中所有数字的重复项。

Duplicate for 7 in 6
Duplicate for 7 in 8

显然,您可能需要连接字符串,并通过调用outputResults.setText()在循环结束时显示它。

此处演示。


1

只需要两个for循环怎么样?

for (int i = 0; i < array.length; i++) {
  for (int j = 0; j < array.length; j++) {
    if (array[i] == array[j]) {
      System.out.println("Duplicate - " + array[i] + " found at index " + i + " and " + j);
    }
  }
}

这是错误的!你总是在评估相同的位置。例如,array[0] == array[0]。 - karlihnos
@karlihnos 假设数组长度为3。循环嵌套。它在i = 0时进入第一个循环。然后在j = 0时进入第二个循环。然后i = 0,j = 1; i = 0,j = 2。现在j = 3!< array.length,因此退出第二个循环。第一个循环递增i。i = 1,j = 0; i = 1,j = 1等。 - Gavin
从op的例子中可以看出:int[] array = {0, 7, 9, 1, 5, 8, 7, 4, 7, 3}。他说:7在位置1、6和8重复出现。在您的代码中,您评估array[0]==array[0],在j完成后,它继续比较array[1],而j将在某个时候成为arrays[1],这意味着再次array[1]=array[1]。因此,基本上您正在将每个数字与其自身进行比较。 - karlihnos

0
一种选项是创建一个 HashMap,其中将值用作键,并为该值指定索引的集合。扫描数组时,如果值不在 HashMap 中,则添加一个新的索引集合。如果值已经在数组中,则提取集合,添加下一个索引并完成迭代。
完成后,遍历 HashMap,任何具有 size() > 1 的值的条目都有重复项。

抱歉,我不知道什么是HashMap。我们在课堂上从未讨论过相关的内容。你能否愿意稍微解释一下?与此同时,我会进行一些研究。 - user1462300
基本上,它是一个哈希表,但是使用Map集合接口实现。http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html - Michael

0

当您遍历数组时,您正在使用行index = p;覆盖任何先前找到的索引。如果要搜索的值只出现一次,则此行有效。让index成为一个字符串,并在到达该行时将其连接起来,以便index += " "+p;。您的代码:

 outputResults.setText(search + " was in the following fields of the array " + index);

然后将打印出正在搜索的值的所有找到的索引。

因此,有几种方法可以完成您的解决方案(一些天真和一些最佳),话虽如此; 当您遇到问题时,您应该仔细考虑您要实现的目标,并弄清楚代码中每行的作用(调试)。


哇,真不敢相信我居然忘了 +=。这个方法完美地解决了问题!当然,我知道有很多种方法可以达到我想要的结果,但就像我之前提到的那样,当你长时间地从事某项工作时,你往往会忘记基础和简单的做事方法。非常感谢你! - user1462300
如果这篇文章帮助您解决了问题,请将其标记为已接受。在赞成票数量下方有一个勾号。 - Donnie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接