我有一个数组,大小可以达到10000.它只有1/2/3/4。我需要找到阵列中有多少1s,2s,3s和4s。这样做的最快方法是什么?我的使用语言是Java。我的代码 -
for(int i=0; i<myArray.length;i++){
int element = myArray[i];
if(element == 1){
onesCount++;
}
else if(element == 2){
twosCount++;
}
else if(element == 3){
threesCount++;
}
else
foursCount++;
}
我希望有一个很好的解决方案。
答案 0 :(得分:7)
int count[5]; //initialize this to 0
for(int i = 0; i<n; i++)
{
count[array[i]]+=1;
}
答案 1 :(得分:2)
您将拥有阵列条目的单独计数器。在找到新的匹配数字时,每个都会增加,因此您必须至少访问每个索引,也就是说您将在O(n)时间内使用算法。可以首选switch语句而不是多个if-else语句:
int[] array = new int[10000];
// ... populate array
int[] counters = new int[4];
for (int i = 0; i < array.length; i++)
{
int temp = array[i];
switch (temp) {
case 1:
counters[0]++;
break;
case 2:
counters[1]++;
break;
case 3:
counters[2]++;
break;
case 4:
counters[3]++;
break;
default:
// to do.
}
}
答案 2 :(得分:2)
没有比你更好的解决方案。可以更灵活,但不会更快。一切都必须至少完成整个阵列的单次传递。
性能优化的唯一区域是避免执行此操作,例如在更新阵列时跟踪计数器。如果值得这么麻烦(可能不是)取决于你需要多久做一次,数组有多大,以及你还需要做些什么。
答案 3 :(得分:1)
如果您使用的是Java 7,则可以使用Fork/Join Framework。 复杂性仍然是O(n)......但对于大型数组来说可能更快
答案 4 :(得分:0)
您可以使用一次通过数组来完成此操作。
只需拥有一个包含四个元素的数组,每个元素代表一个值(1/2/3/4),对于原始数组中的每个元素,您可以增加“count”数组中相应位置的计数。 这将使它成为O(n)。
答案 5 :(得分:0)
如果您可以使用地图或自定义类。如果你不能,你必须遍历整个数组。如果你现在没有遇到性能问题,我会尽量做迭代。
答案 6 :(得分:0)
如果开关版本(deporter)或noMAD的版本不是最好的,试试这个:
for (int i = 0; i < myArray.length; i++) {
int element = myArray[i];
if (element > 2) {
if (element == 4) {
foursCount++;
} else
threesCount++;
} else {
if (element == 2)
twosCount++;
else
onesCount++;
}
}
它可以节省少量的比较。但这取决于真实的数据。如果您对数据很幸运,那么直接版本可能会做得更好。
除此之外,使用并行性总是值得尝试大数据。
答案 7 :(得分:0)
我认为你不会比这更快:
final int[] counts = new int[5];
final int length = array.length - 1;
for (int i = 0; i < length; i++) {
counts[array[i]]++;
}
请注意,在 for 循环中,未引用 array.length 。它被放入一个局部的final int中,这避免了在每次迭代中取消引用array.length。
我对此方法进行了基准测试,该方法使用了switch..case语句,只使用了本地堆栈变量:
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
for (int i = array.length - 1; i >= 0; i--) {
switch (array[i]) {
case 1:
count1++;
break;
case 2:
count2++;
break;
case 3:
count3++;
break;
case 4:
count4++;
break;
}
}
结果是第一种方法需要17300纳秒,而switch..case方法需要79800纳秒。 [更新:忘记将纳秒除以10.我每次运行10次。]
注意:在确定基准测试之前,我首先警告了VM。