Java复制了不同的唯一数组值

时间:2012-08-10 17:10:14

标签: java

我正在努力解决这个问题,但我不知道如何......

Values[10] = {1,1,4,4,2,3,3,2,1,3}

打印:

{1,2,3,4} or {1,4,2,3} (not sorted, any order, but distinct)

我还需要计算每个数字发生的次数,没有排序,新数组或布尔方法或其他数据结构,请告知我被卡住了。

是否有一种简单的方法可用于打印唯一值/不同值?

4 个答案:

答案 0 :(得分:1)

另一种解决方案,无需创建其他对象:

Arrays.sort(values);
for(int i = 0; i < values.length; i++) {
    if (i == 0 || value[i] != value[i-1]) {
        System.out.println(values[i]);
    }
}

我能想到的最短的解决方案:

Integer[] values = {1,1,4,4,2,3,3,2,1,3};
Set<Integer> set = new HashSet<Integer>();
set.addAll(Arrays.asList(values));
System.out.println(set); 

答案 1 :(得分:1)

如果您愿意销毁当前阵列,则可以实现。并且假设数组的类型为Integer(可以为空),或者如果没有,则所有int都有一些限制,因此您可以使用-1

for(int i = 0;  i < values.length; i++){               //for entire array             

    Integer currVal = values[i];                       // select current value
    int count = 1;                                     // and set count to 1

    if(currVal != null){                               // if value not seen

        for( int j = i + 1; j < values.length; j++){   // for rest of array
            if(values[j] == currVal){                  // if same as current Value 
                values[j] = null;                      // mark as seen
                count++;                               // and count it 
            } 
        }
        System.out.print("Number : "  + currVal + "  Count : " + count + "\n");
                                                       //print information
    }
                                                       // if seen skip.
}

简单来说,在2个循环中遍历数组,大约是O(n ^ 2)时间。 转到索引i。如果尚未看到索引(不为null),则遍历数组的其余部分,标记具有相同值的任何索引(使其为空)并递增计数可变量。在循环结束时打印值和计数。如果看到Index(为空),请跳过并转到下一个索引。在两个循环结束时,所有值都将保留为null。

Input : Values[] = {1,1,4,4,2,3,3,2,1,3}


Output : Values[] = {1,null,4,null,2,3,null,null,null,null}
          Number : 1 Count : 3
          Number : 4 Count : 2
          Number : 2 Count : 2
          Number : 3 Count : 3

编辑:纠正了输出中的错误,评论者指出。

答案 2 :(得分:1)

假设值保证为整数,您也可以通过递增检查值,扫描数组,对数组中的检查值的数量求和,将其添加到累加器并在累加器和循环时循环来实现; array.length。

像这样(未经测试):

public void checkArray(int[] toCheck) {
    int currentNum = 0;
    int currentCount = 0;
    int totalSeen = 0;

    StringBuilder sb = new StringBuilder();

    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;
    for(int i=0; i<toCheck.length; i++) {
        min = Math.min(toCheck[i], min);
        max = Math.max(toCheck[i], max);
    }

    System.out.print("{ ");
    for(currentNum = min; currentNum < max; currentNum++) {
        for(int i=0; i<toCheck.length; i++) {
            if(toCheck[i] == currentNum) currentCount++;
        } 

        if(currentCount != 0) {
            if(currentNum == min) System.out.print(currentCount + "(" +currentCount+ ")");
            else System.out.print(", " + currentCount + " (" +currentCount+ ")");
        }
        totalSeen += currentCount;
        currentCount = 0;
    }
    System.out.println(" }");
}

应该注意的是,虽然这在技术上满足了您的所有要求,但它的效率效率低于gbtimmon的方法。

例如,如果您的整数为{1,2,3,150000},它将不必要地旋转4到149999之间的所有值。

编辑:从tbitof的建议中添加了更好的限制。

答案 3 :(得分:0)

你的问题对我来说并不十分清楚,因为听起来你想做这些事情而根本不创造任何额外的对象。但是如果它只是不创建另一个数组,你可以使用Map<Integer, Integer>,其中键是原始数组中的数字,值是你看到它的次数。然后在最后,您可以查找所有数字的计数,并使用Map.keyset()打印出所有密钥

编辑:例如:

Map<Integer,Integer> counts = new HashMap<Integer, Integer>();
for( int i : values ) {
    if( counts.containsKey(i) ) {
        counts.put(i, counts.get(i) + 1);
    } else {
        counts.put(i, 1);
    }
}

// get the set of unique keys
Set uniqueInts = counts.keyset();