在Java中计算数组中不同的值

4
我正在编写一段代码,其中有一个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;
    }
}

有人能帮忙吗?


3
这段代码格式很差,甚至无法运行。请确保您的程序没有编译错误,并且在发布前进行适当的格式化。 - Keppil
differentValuesUnsorted函数顶部的那些if else-if else语句,它们只适用于长度小于2的数组,还是应该遍历存储了多个整数的数组? - Ungeheuer
你的for循环也有问题。如果 a[1] 的值大于数组的长度会发生什么?将会出现AIOOB错误。 - Ungeheuer
也许我误解了任务,但它说(翻译成英语): 如果数组为空(长度为0),则该方法应返回0,因为空数组中没有0个不同的值。 我一直认为,如果数组有一个值,如int [] a = {2},那么就没有不同的值。所以,我一直在尝试使用if / else-if / else语句使结果变为: int [] a = {2} => 0个不同的值,int [] a = {2,2} => 0个不同的值,但int [] a = {1,2} => 2个不同的值。 - user4828774
但要注意,如果我们的数组长度大于2(假设是3),并且在else if(a[0] == a[1])这行时前两个整数相同,它将返回0而不是2。你的循环依然存在问题。 - Ungeheuer
@JohnnyCoder,你说得对。明天需要进一步研究这个问题。 - user4828774
9个回答

8
实际上,这比大多数人所认为的要简单得多,这种方法完全可行:
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不包含数组参数中的整数,则将该元素添加到arrayList。
  • 如果arrayList包含int数组参数中的元素,则不执行任何操作。(不要将该值添加到ArrayList中)
N.B:这意味着ArrayList包含int[]中的所有数字,并删除重复数字。
3)ArrayList的大小(类似于数组的length属性)将是提供的数组中不同值的数量。

试用

输入:

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

Output: 6


3

首先创建一个不同值数组,可以使用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
除了@RamanSB指出的排序问题之外,发布一段代码块并说“试试这个”是不可接受的回答。SO旨在帮助人们理解代码及其可能存在的任何错误。您需要解释您的代码功能,无论它对您来说多么简单明了。 - Ungeheuer
请尝试阅读我的评论。你的回答仍然不可接受。如果你不相信我关于你的回答应该如何格式化的说法,可以查看元数据。 - Ungeheuer

1
对于小数组,这是一种快速简洁的方法,不需要分配任何额外的临时对象:
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),对于大型数组而言比其他解决方案慢得多。 - Björn Lindqvist
对于大型数组,您需要找到一种使用某种哈希索引的方法,但Java HashSet是存储整数的非常糟糕的方式,并且具有很大的开销。我进行了基准测试,并发现交叉点约为25个元素的数组。在此之下,上述方法更快(例如,对于10个元素的数组,速度快3倍)。在以上情况下,HashSet开始获得优势,到1000个元素时,它的速度快了10倍。 - rghome
我在答案中添加了“适用于小数组”的限定词。 - rghome

1
你可以使用 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
@PKuhn 为什么应该是0?{3,3,4,4}有两个不同的元素:3和4。 - Fernando Matsumoto
1
代码正在寻找不同元素的数量,因此在3,3,4,4中有0个唯一元素,但是根据我的理解,HashSet仍将保留3和4,而您的代码将返回2,而不是0。 - Ungeheuer
@JohnnyCoder,这个问题是在寻找不同元素的数量(2个不同的元素:3和4),还是唯一元素的数量(0个唯一元素)?我的理解是他在寻找不同的值。如果我理解错了,那么我会删除这个答案。 - Fernando Matsumoto
也许我表达不够清晰。Matsumoto,你的理解是正确的。我正在寻找不同的元素。因此,在3,3,4,4中,答案是2。 - user4828774
显示剩余4条评论

0

试试这个...使用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());
}
}

0

尝试一下这个简单的代码片段。

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();
}

和之前的答案相同且无法编译。 - rghome

0

试试这个:

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


0

这个怎么样?

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

是的?有什么问题吗?您想要改进建议吗?还是这是对问题的回答?如果是这样,请添加一些关于它如何工作以及为什么有帮助的解释。 - Yunnosch

-1
使用集合来去除重复项。
 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}; 我得到了 "run: 4"。 应该是 5。 - user4828774
我认为HashSet没有接受int数组的构造函数。 - Maurice Perry

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