0

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

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

4 回答 4

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); 
于 2012-08-10T17:22:24.160 回答
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。如果尚未看到索引(不为空),则遍历数组的其余部分,将任何索引标记为与所见相同的值(使其为空)并增加计数变量。在循环结束时打印值和计数。如果已经看到索引(为空),则跳过并转到下一个索引。在两个循环结束时,所有值都将保留为空。

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

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

于 2012-08-10T17:29:57.197 回答
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 的方法。

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

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

于 2012-08-10T18:08:56.837 回答
0

你的问题对我来说不是很清楚,因为听起来你想要做这些事情而不创建任何额外的对象。但如果只是不创建另一个数组,您可以使用 a 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();
于 2012-08-10T17:18:00.030 回答