【问题标题】:counting number of unique elements计算唯一元素的数量
【发布时间】:2015-04-18 22:56:30
【问题描述】:

嗨,所以我应该在数组排序后计算唯一元素的数量,不包括重复项,但我得到了错误的输出。

In in = new In(args[0]);
int[] whitelist = in.readAllInts();
Arrays.sort(whitelist);

int count = 0;
   for (int i = 0; i < whitelist.length; i++) {
       if (whitelist[i] == whitelist[count]) {
           count++;
       }
   }
while (!StdIn.isEmpty()) {
    int key = StdIn.readInt();
    rank(key, whitelist);
}
   System.out.println(count);

} }

预期输出:java InstrumentedBinarySearch tinyW.txt

65

得到:16

我计算了重复的数量还是什么?

【问题讨论】:

标签: java arrays duplicates


【解决方案1】:
  int flag = 0;
  int count = 0;
       for (int i = 0; i < whitelist.length; i++) //Element to be checked for
  {
           for (int j=0; j< whitelist.length ; j++) //Loop that goes through the whole array 
       {
               if (whitelist[i] == whitelist[j]) //checks if there are duplicates
               {
                   flag++; // count
               }
       }
    if( flag==1) //There should be only 1 instance of the element in the array and that is the element itself
    { 
       System.out.println(whitelist[i]); //displays unique element
       count++; // Keeps count 
    }
 }

【讨论】:

  • 这是我在您编辑问题之前的回答。此代码将查找数组中的唯一元素。
  • 我添加了 cmets 来解释每一行。 OPs 代码使用白名单 [count],这没有任何意义,因为计数是重复计数的数量,并且它不会像我的代码中的 j 变量一样浏览数组的其余部分。希望对您有所帮助。
  • 这个方法给我的答案是 10 而不是 65
【解决方案2】:

此算法计算数组中有多少个不同的唯一数字。出现不止一次的数字仅计为 1。我假设这就是您的意思,而不是“仅出现一次的数字”。

正如另一个答案中提出的那样,有一种更简单的方法可以做到这一点,但它需要嵌套的 for 循环,因此以二次复杂度执行。我下面的算法试图在与数组大小成正比的线性时间内解决问题。

int uniquesFound = 0;

// Assume that array is sorted, so duplicates would be next to another.
// If we find duplicates, such as 12223, we will only count its last instance (i.e. the last '2')
for (int i = 0; i < whitelist.length; i++) {

    // If we are at the last element, we know we can count it
    if (i != whitelist.length - 1) {
        if (whitelist[i] != whitelist[i+1]) {
            uniquesFound++;
        }
        else {
            // Nothing! If they are the same, move to the next step element
        }
    } else {
        uniquesFound++;
    }
}

例如,给定数组:

{1,2,3} 这将产生 3,因为有 3 个唯一数字

{1,2,3,3,3,4,4,4,5} 这将产生 5,因为仍有 5 个唯一数字

【讨论】:

  • 为了更清楚,我应该在排序后删除白名单中的重复键。因此,检查的密钥数量应该小于未删除重复项时的数量,根据您的逻辑,这似乎是正确的。但它没有产生任何结果,只是空白
  • 如果您的排序步骤也恰好删除了重复键,那么唯一项的数量就等于数组的长度。这是因为如果您删除重复的键,则数组中只剩下唯一的数字。
  • 在这种情况下如何打印唯一键的数量?
  • 如果您告诉我白名单已排序并且已删除所有重复键,那么唯一键的数量就是白名单数组的长度。只需打印 whitelist.length。如果你还是一头雾水,不如给我举个例子,告诉我白名单里有什么,答案应该是什么。
  • 奇怪的是你的解决方案给了我和我发布的一样的答案。
【解决方案3】:

首先让我们看看你的循环:

for (int i = 0; i < whitelist.length; i++) {
    if (whitelist[i] == whitelist[count]) {
        count++;
    }
}

您应该比较列表中的连续元素,例如 whitelist[0] == whitelist[1]?, whitelist[1] == whitelist[2]?, whitelist[3] == whitelist[4]?,等等。在这种情况下,whitelist[i] == whitelist[count] 毫无意义。

现在你有两个选择:

一个。当您找到两个相等的连续元素并从数组的总大小中减去结果时,增加您的计数器:

for (int i = 0; i < whitelist.length - 1; i++) {
    if (whitelist[i] == whitelist[i + 1]) {
        count++;
    }
}
int result = whitelist.length - count;

b.更改条件以计算不相等的连续元素之间的转换。由于是在计算转换的数量,所以需要在最后加上1count 才能得到数组中唯一元素的数量:

for (int i = 0; i < whitelist.length - 1; i++) {
    if (whitelist[i] != whitelist[i + 1]) {
         count++;
    }
}
int result = count + 1;

请注意,在这两种情况下,我们只循环到whitelist.length - 1,因此whitelist[i + 1] 不会超出范围。

【讨论】:

    猜你喜欢
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多