【问题标题】:Count different values in array in Java在Java中计算数组中的不同值
【发布时间】:2015-12-03 08:03:12
【问题描述】:

我正在编写一个代码,其中我有一个 int[a] 并且该方法应该返回唯一值的数量。示例:{1} = 0 个不同的值,{3,3,3} = 0 个不同的值,{1,2} = 2 个不同的值,{1,2,3,4} = 4 个不同的值等。我不允许对数组进行排序

问题是我的方法可能不起作用。我的 for 语句有问题,我无法弄清楚。

public class Program
{

    public static void main(String[] args)
    {
        int[] a = {1, 2, 3, 1};

        System.out.println(differentValuesUnsorted(a));
        //run: 4 //should be 3
    }

public static int differentValuesUnsorted(int[] a)
{
    int values;      //values of different numbers

    if (a.length < 2)
    {
        return values = 0;
    }else if (a[0] == a[1])
    {
        return values = 0;
    }else
    {
        values = 2;
    } 

    int numberValue = a[0];
    for (int i = a[1]; i < a.length; i++)
    {
        if (a[i] != numberValue)
        {
             numberValue++;
             values++;
        }
    }
        return values;
    }
}

有人可以帮忙吗?

【问题讨论】:

  • 这段代码格式很差,甚至无法运行。请确保您的程序没有任何编译错误,并且在发布之前格式正确。
  • if else-if else differentValuesUnsorted 顶部的那些语句,它们只是针对长度小于 2 的数组,还是应该通过具有多个 int 存储在其中?
  • 你的 for 循环也很糟糕。如果a[1] 的值大于数组的长度会怎样?发生 AIOOB 错误
  • 也许我误解了这个任务,但它说(翻译成英文):如果数组为空(长度为 0),该方法应返回 0,因为空数组中有 0 个不同的值.我一直在想,这意味着如果数组有一个值,例如 int[] a = {2} ,则没有不同的值。因此,我一直在尝试使用 if/else-if/else 语句使结果变为: int[] a = {2} => 0 different values, int[] a = {2,2} => 0不同的值,但 int[] a = {1,2} => 2 个不同的值。
  • 请注意,如果数组长度为 2 或更大,出于我们的目的,可以说大于 2,因此 3 命中 else if(a[0] == a[1]) 行,并且前 2 个整数是相同的,它会返回 0,而它应该是 2,而你的 for 循环仍然有问题

标签: java arrays for-loop


【解决方案1】:

首先创建不同的值数组,它可以简单地使用HashSet创建。

然后alreadyPresent.size() 将提供许多不同的值。但是对于诸如 -{3,3,3} = 0 的情况(数组包含相同的元素); alreadyPresent.size() 的输出为 1。为此使用这个简单的过滤器

if(alreadyPresent.size() == 1)){
    return 0;
}

以下代码将给出不同值的计数。

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Demo {

  public static void main(String[] args)
  {
       int array[] = {9,9,5,2,3};
       System.out.println(differentValuesUnsorted(array));
  }

  public static int differentValuesUnsorted(int[] array)
  {

     Set<Integer> alreadyPresent = new HashSet<Integer>();

     for (int nextElem : array) {
         alreadyPresent.add(nextElem);
     }

     if(alreadyPresent.size() == 1){
         return 0;
     }

     return alreadyPresent.size();

  }
}

【讨论】:

  • "我不允许对数组进行排序"
  • 除了@RamanSB 发布的代码块指出的排序问题之外,“试试这个”是一个不可接受的答案。 SO 是关于帮助人们理解代码和他们可能犯的任何错误。无论您觉得多么简单,您都需要解释代码的功能。
  • 尝试阅读我的评论。你的答案仍然是不可接受的。如果您不相信我所说的关于您的答案应该如何格式化,请查看元数据。
【解决方案2】:

您可以使用HashSet,它只能包含唯一元素。 HashSet 将删除重复的项目,然后您可以获得集合的大小。

public static int differentValuesUnsorted(int[] a) {
    Set<Integer> unique = new HashSet<Integer>();
    for (int val : a) {
        unique.add(val); // will only be added if a is not in unique
    }
    if (unique.size() < 2) { // if there are no different values
        return 0;
    }
    return unique.size();
}

【讨论】:

  • 不能解决问题,因为据我了解 {3,3,4,4} 应该是 0
  • @PKuhn 为什么应该是 0? {3,3,4,4} 有两个不同的元素:3 和 4。
  • 代码正在寻找 不同 元素的数量,因此在 3,3,4,4 中有 0 个唯一元素,但我的理解是 HashSet剩下 3 和 4,您的代码将返回 2,而不是 0
  • @JohnnyCoder 操作员是在寻找不同元素的数量(2 个不同的元素:3 和 4)还是唯一元素的数量(0 个唯一元素)?我的理解是他在寻找不同的价值观。如果这是错误的,那么我将删除答案
  • @JohnnyCoder:根据操作的代码,他确实在寻找不同值的数量:{1,2,3,1} 应该返回 3。如果他正在寻找唯一值,则返回值为 2。
【解决方案3】:

使用集合删除重复项

 public static int differentValuesUnsorted(int[] a) {
     if (a.length < 2) {
         return 0;
     }

     Set<Integer> uniques = new HashSet<>(a);
     return singleUnique.size();
 }

【讨论】:

  • 运行此方法时,我得到了错误的答案。使用 int[] a = {0,2,3,5,4,3};我得到“运行:4”。应该有 5 个。
  • 我不认为HashSet 有一个构造函数,它接受ints 的数组。
【解决方案4】:

这实际上比大多数人想象的要简单得多,这种方法效果很好:

public static int diffValues(int[] numArray){
    int numOfDifferentVals = 0;

    ArrayList<Integer> diffNum = new ArrayList<>();

    for(int i=0; i<numArray.length; i++){
        if(!diffNum.contains(numArray[i])){
            diffNum.add(numArray[i]);
        }
    }

    if(diffNum.size()==1){
            numOfDifferentVals = 0;
    }
    else{
          numOfDifferentVals = diffNum.size();
        } 

   return numOfDifferentVals;
}

让我带你了解一下:

1) 提供一个 int 数组作为参数。

2) 创建一个包含整数的 ArrayList:

  • 如果该数组列表包含数组中的整数 作为参数提供,然后将该元素添加到数组参数中 到数组列表
  • 如果该 arrayList DOES 包含 int 数组参数中的该元素,则不执行任何操作。 (不要将该值添加到数组列表中)

注意:这意味着 ArrayList 包含 int[] 中的所有数字,并删除重复的数字。

3) ArrayList 的大小(类似于数组的长度属性)将是提供的数组中不同值的数量。


试用

输入

  int[] numbers = {3,1,2,2,2,5,2,1,9,7};

输出:6

【讨论】:

    【解决方案5】:

    试试这个:

    import java.util.ArrayList;
    public class DifferentValues {
    
     public static void main(String[] args)
      {
        int[] a ={1, 2, 3, 1};
        System.out.println(differentValuesUnsorted(a));
      }
    
     public static int differentValuesUnsorted(int[] a)
     {
       ArrayList<Integer> ArrUnique = new ArrayList<Integer>();
       int values=0;      //values of different numbers
       for (int num : a) {
           if (!ArrUnique.contains(num)) ArrUnique.add(num);
       }
       values = ArrUnique.size();
       if (values == 1) values = 0;       
       return values;
     }
    }
    

    输入:{1,1,1,1,1} - 输出: 0
    输入:{1,2 ,3,1} - 输出: 3

    【讨论】:

      【解决方案6】:

      对于小型数组,这是一种快速简洁的方法,不需要分配任何额外的临时对象:

      public static int uniqueValues(int[] ids) {
          int uniques = 0;
      
          top:
          for (int i = 0; i < ids.length; i++) {
              final int id = ids[i];
              for (int j = i + 1; j < ids.length; j++) {
                  if (id == ids[j]) continue top;
              }
              uniques++;
          }
          return uniques;
      }
      

      【讨论】:

      • 由于嵌套循环,该解决方案的时间复杂度为 O(n^2),并且比其他大型数组解决方案慢得多。
      • 没错,对于大型数组,您可能希望找到一种使用某种哈希索引的方法,但 Java HashSet 是一种非常糟糕的存储整数的方法,并且开销很大。我做了一个基准测试,发现交叉点大约是一个 25 个元素的数组。在此之下,上述方法更快(例如,对于 10 元素数组,速度快 3 倍)。上面,HashSet 开始增长,并且通过 1000 个元素,它的速度提高了 10 倍。
      • 我在答案中添加了限定词“for small arrays”。
      【解决方案7】:

      试试这个...使用 ArrayList 非常简单。你甚至不需要两个循环。继续

      import java.util.*;
      public class distinctNumbers{
      
       public static void main(String []args){
          int [] numbers = {2, 7, 3, 2, 3, 7, 7};
          ArrayList<Integer> list=new ArrayList<Integer>();
          for(int i=0;i<numbers.length;i++)
          {
      
              if(!list.contains(numbers[i]))  //checking if the number is present in the list
              {
                  list.add(numbers[i]); //if not present then add the number to the list i.e adding the distinct number
              }
      
          }
          System.out.println(list.size());
      }
      }
      

      【讨论】:

        【解决方案8】:

        试试这个简单的代码 sn-p。

        public static int differentValuesUnsorted(int[] a)
        {
            ArrayList<Integer> list=new ArrayList<Integer>();   //import java.util.*;
            for(int i:numbers)                                  //Iterate through all the elements
              if(!list.contains(i))                             //checking for duplicate element
                list.add(i);                                    //Add to list if unique
            return list.size();
        }
        

        【讨论】:

        • 与上一个答案相同,无法编译。
        【解决方案9】:

        这个怎么样?

        private <T> int arrayDistinctCount(T[] array) {
            return Arrays.stream(array).collect(Collectors.toSet()).size();
        }
        

        【讨论】:

        • 是吗?怎么样?你的代码有问题吗?您想要改进它的建议吗?或者这应该是问题的答案?在这种情况下,请添加一些关于它是如何工作的以及它为什么有用的解释。
        猜你喜欢
        • 2020-01-03
        • 1970-01-01
        • 2017-12-28
        • 1970-01-01
        • 2015-06-01
        • 2017-11-09
        • 1970-01-01
        • 2012-10-02
        • 1970-01-01
        相关资源
        最近更新 更多