我一直在尝试编写代码,该代码在排序数组中找到也有重复项的唯一值。
到目前为止,我写过:
public static int numUnique (double[] list) {
int counter = 0;
if (Array.getLength(list) < 1) {
return Length.list);
}
else{
for (int i=0; i < Length.list); i++){
for (int j=i+1; j< Length.list); j++){
if (list[i] != list[j]){
newrArray[i] = list[i];
counter++;
}
}
}
}
return counter;
}
输入:
{31, 31, 31, 31, 33, 46, 46, 46, 46, 46, 52, 65, 65, 66, 75, 98, 98}
预期产出:
8
我无法使用HashSet
或ArrayList
。我认为唯一可行的选择是从一个数组复制到另一个数组然后计算新数组中的内容(假设只有唯一值被复制到新数组中)。
答案 0 :(得分:3)
你知道这个数组的最大值吗?如果它足够小,你可以创建一个该大小的布尔数组,如果在原始数组中找到该值,则将值设置为true。
编辑:这称为计数排序。
示例:
boolean[] found = new boolean[max];
for(int i : list)
found[i] = true;
int unique = 0;
for(int i = 0; i < found; i++)
if(found[i]) unique++;
如果没有,请计算唯一元素的数量并插入它们。
public int uniqueAmount(double[] list) {
double last = Double.NaN;
int unique = 0;
for(int i = 0; i < list.length; i++)
if(last != (last = list[i]))
unique++;
return unique;
}
public double[] uniqueValues(double[] list) {
int unique = uniqueAmount(list);
double[] found = new double[unique];
double last = Double.NaN;
last = list[0];
found[0] = last;
for(int i = 0, index = 1; i < list.length; i++)
if(last != list[i]) {
found[index++] = list[i];
last = list[i];
}
return found;
}
经过测试,确实有效。
如果您拨打uniqueAmount
,则会返回8,如果您致电[31.0, 33.0, 46.0, 52.0, 65.0, 66.0, 75.0, 98.0]
,则会返回数组uniqueValues
。
答案 1 :(得分:1)
您也可以使用流来执行此操作。我在数组中从第一个索引到最后一个索引创建一个IntStream。然后我使用&#34; indexOf(elem)&#34;过滤元素。数组首次出现的方法。之后,使用&#34; mapToObj()&#34;我可以获得适当的元素并使用&#34; count()&#34;得到他们的金额。
例如:
List<Integer> d = Arrays.asList(31, 31, 31, 31, 33, 46, 46, 46, 46, 46, 52, 65, 65, 66, 75, 98, 98);
long result = IntStream.range(0, d.size())
.filter(a -> a == d.indexOf(d.get(a)))
.mapToObj(d::get)
.count();
System.out.println(result);
答案 2 :(得分:0)
你过分复杂了一些事情:
由于数组已排序,您需要做的就是检查数组中的值和它之前的值是否相等。如果他们没有增加计数,则继续下一个值:
int uniqueNum(double[] d){
if(d.length < 2)
return d.length;
int count = 0;
//choose an initial previous value that differs from the first element in the array
double prev = (d[0] == 1.0 ? 2.0 : 1.0);
for(double v : d){
//ignore duplicate values
if(v == prev)
continue;
count++;
prev = v;
}
return count;
}
这是有效的,因为在排序数组中,重复值总是形成一个序列。
为什么您的代码无效:
for (int i=0; i < Array.getLength(list); i++){
for (int j=i+1; j< Array.getLength(list); j++){
if (list[i] != list[j]){
catcherArray[i] = list[i];
counter++;
}
}
}
此代码不计算数组中不同值的数量,但对于数组中的任何索引,该值的数量与该索引处的值不同。
答案 3 :(得分:0)
不需要复制任何数组或使用额外的数据结构,因为您按排序顺序给出了数组。这意味着当list [i]!= list [i + 1]时,数组中不会再出现任何事件。这对您有很大帮助,并允许您对阵列进行单次遍历以找到解决方案。这是一个没有额外收藏的简单解决方案
public static int FindTotalUniqueNumbers(double[] list)
{
if(list.length < 0)
return 0;
double currentNumber = list[0];
int currentCount = 1;
for(int i = 1; i < list.length; i++)
{
if(list[i] != currentNumber)
{
currentCount++;
currentNumber = list[i];
}
}
return currentCount;
}
实施例
double[] list = new double[] {31, 31, 31, 31, 33, 46, 46, 46, 46, 46, 52, 65, 65, 66, 75, 98, 98};
System.out.println(FindTotalUniqueNumbers(list));
输出
8
答案 4 :(得分:0)
对数组进行排序,这意味着重复值彼此相邻。这对我们来说是个好消息,因为一旦我们看到与前一个不同的价值,我们肯定知道以前的价值不会再出现。我们可以进行线性扫描:
int countDistinct(double [] numbers) {
if (numbers == null || numbers.length == 0) return 0;
int c = 1, n = numbers.length;
// The previous value, initialized to the first element
double prev = numbers[0];
// Start loop from the second element
for (int i = 1; i < n; i++) {
if (prev != numbers[i]) {
c++;
prev = numbers[i];
}
}
return c;
}
答案 5 :(得分:0)
由于此代码段不需要您对数组进行排序,因此考虑到元素已排序,可以编写更高效的版本。但是,这对于未排序的数组非常有效。
public static int numUnique(double[] list) {
double[] tempArray = new double[0];
int index;
for (double element : list) {
boolean matchFound = false;
if (tempArray.length > 0) {
for (double d : tempArray) {
if (d == element) {
matchFound = true;
break;
}
}
}
if (!matchFound) {
tempArray = Arrays.copyOf(tempArray, tempArray.length + 1);
tempArray[tempArray.length - 1] = element;
}
}
return tempArray.length;
}
答案 6 :(得分:0)
您可以根据数组使用IntStream distinct()或DoubleStream distinct()。
double[] doubleArray ={31.0, 31.0, 31.0, 31.0, 33.0, 46.0, 46.0, 46.0, 46.0, 46.0, 52.0, 65.0, 65.0, 66.0, 75.0, 98.0, 98.0};
long count = DoubleStream.of(doubleArray).distinct().count();
System.out.println(count);
输出:
8
如果你有int数组,你可以使用IntStream distinct()
int[] intArray = {31, 31, 31, 31, 33, 46, 46, 46, 46, 46, 52, 65, 65, 66, 75, 98, 98};
long count = IntStream.of(intArray).distinct().count();
System.out.println(count);
输出:
8