下面的代码为我提供了数组最大值的索引:
public static void main(String[] args) {
float[] elementList = new float[7];
elementList[0] = 8F;
elementList[1] = 5F;
elementList[2] = 4F;
elementList[3] = 3F;
elementList[4] = 0F;
elementList[5] = 8F;
elementList[6] = 6F;
// findLargestNumberLocations(elementList);
largestNumbers(elementList);
}
private static void largestNumbers(float[] numbers) {
float largeNumber = numbers[0];
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] > largeNumber) {
largeNumber = numbers[i];
}
}
for (int j = 0; j < numbers.length; j++) {
if(largeNumber == numbers[j]){
System.out.println("largest number index "+j);
}
}
}有什么优化的方法吗?
发布于 2013-12-12 15:57:49
在这种情况下,您的性能不会很糟糕,但是,对于非常大的数组,您可能会遇到问题。
还有,你的代码里有个bug .如果输入数组为空怎么办?然后,您将得到一个ArrayIndexOutOfBoundsException:
float largeNumber = numbers[0];做事情的方法总是不止一种,但是,我想在这里发布一个答案,因为一种可能的解决方案(根据数据大小可能比您的解决方案快,也可能不快)与最近发布的另一个CodeReview问题有着非常密切的关系。当我回答这个问题时,我只能想到一些人为的例子,说明什么时候使用前后增量是“正确的”。这是一个很好的例子.
见这里的答案:在for循环声明中增加多个变量是错误的做法吗?
因此,这里有一个很好的例子,说明了count和index在for循环中是如何和何时相关的,以及它们的增量方式。我在结尾有一些笔记:
private static int[] findLargeNumberIndices(float[] numbers) {
// create an array of at least 8 members.
// We may need to make this bigger during processing in case
// there's more than 8 values with the same large value
int[] indices = new int[Math.max(numbers.length / 16 , 8)];
// how many large values do we have?
int count = 0;
// what is the largest value we have?
float largeNumber = Float.NEGATIVE_INFINITY;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] > largeNumber) {
// we have a new large number value... reset our history....
largeNumber = numbers[i];
// setting count to zero is enough to 'clear' our previous references.
count = 0;
// we know there's space for at least index 0. No need to check.
// note how we post-increment - this is a 'pattern'.
indices[count++] = i;
} else if (numbers[i] == largeNumber) {
// we have another large value.
if (count == indices.length) {
// need to make more space for indices... increase array by 25%
// count >>> 2 is the same as count / 4 ....
indices = Arrays.copyOf(indices, count + (count >>> 2));
}
// again, use the post-increment
indices[count++] = i;
}
}
// return the number of values that are valid only.
return Arrays.copyOf(indices, count);
}关于此代码的说明:
System.out.println(...))现在在方法之外。i索引是如何在for-循环中产生的,但是每次在数组中使用它时,count都是递增的。发布于 2013-12-12 07:08:04
您的代码不只是查找最大数字的索引。它找到最大的数字,然后再搜索与该值匹配的任何索引。
下面是一种使用较少搜索(伪代码)的方法:
largestValue = numbers[0];
vector largestIndices; // Will store all indices of largestValue as you search
largestIndices.add(0); // In case numbers[0] = the true largest value
for (i = 1; i < numbers.size(); i++) { // don't need to compare index 0
if (numbers[i] > largestValue) {
largestValue = numbers[i]; // Update largestValue
largestIndices.clear(); // Get rid of indices of smaller values
largestIndices.add(i); // Add this index
}
else if (numbers[i] == largestValue) {
largestIndices.add(i); // Add this index
}
}
for (j = 0; j < largestIndices.size(); j++) {
// no searching necessary!
print(largestIndices[j]);
}这可能会使用更多的数据访问,但会节省搜索时间(对于大型数组来说很重要)。
发布于 2013-12-12 08:41:12
函数启动后的新行是预期的吗?
private static void largestNumbers(float[] numbers) {这个函数可以有一个更好的名称,函数应该有一个动词作为名称,而不是形容词。
private static void printLargestNumbersIndex(float[] numbers)这是更详细的,但您立即知道该函数的作用。
float largeNumber = numbers[0];很小,但我叫它largestNumber。
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] > largeNumber) {
largeNumber = numbers[i];
}
}foreach循环将更适合于这种用例。
for (float number : numbers) {
if (number > largestNumber) {
largestNumber = number;
}
}通常总是尝试使用foreach循环而不是for循环,除非您需要知道元素的索引(这在第二个循环中是这样的)。
for (int j = 0; j < numbers.length; j++) {对我自己来说,我尽量避免一个字母的变量(只有坐标,x y z除外),这个观点肯定是有争议的和不标准的,但是我认为使用index作为变量会获得很大的可读性。
for (int index = 0; index < numbers.length; index++) {if(largeNumber == numbers[j]){请始终记住,将浮点数与==进行比较是有问题的。
System.out.println("largest number index "+j);理想情况下,从代码结构和重用的角度来看,您的函数将返回包含所有已找到索引的int[]或Collection<Integer>。这将使它很容易重用。
float[] elementList = new float[7];
elementList[0] = 8F;
elementList[1] = 5F;
elementList[2] = 4F;
elementList[3] = 3F;
elementList[4] = 0F;
elementList[5] = 8F;
elementList[6] = 6F;可以使用值直接初始化数组。
float[] elementList = new float[] {8f, 5f, 4f, 3f, 0f, 8f, 6f};而且,elementList并不是一个很好的名字。
https://codereview.stackexchange.com/questions/37201
复制相似问题