Java 求数组中的最小值和最大值
这是一个非常基本的算法(无法变得更简单),但我被难倒了。我们有一个元素数组,我们必须确定最小值和最大值 通常的方法是遍历数组,找到最小值和最大值,即2n 稍微更有效的方法是首先成对比较数组的连续元素,以确定任意两个元素的最大值和最小值(n/2比较)。我们现在有n/2最小和n/2最大元素。现在我们可以得到n/2+n/2+n/2(上一步)=3/2*n或1.5n的最终最大值和最小值 那很好。从理论上讲,在第二种情况下,代码运行所需的时间应该更少,因为我们所做的比较更少。但是,当我运行代码时,结果是相反的 我的代码片段如下:Java 求数组中的最小值和最大值,java,arrays,algorithm,Java,Arrays,Algorithm,这是一个非常基本的算法(无法变得更简单),但我被难倒了。我们有一个元素数组,我们必须确定最小值和最大值 通常的方法是遍历数组,找到最小值和最大值,即2n 稍微更有效的方法是首先成对比较数组的连续元素,以确定任意两个元素的最大值和最小值(n/2比较)。我们现在有n/2最小和n/2最大元素。现在我们可以得到n/2+n/2+n/2(上一步)=3/2*n或1.5n的最终最大值和最小值 那很好。从理论上讲,在第二种情况下,代码运行所需的时间应该更少,因为我们所做的比较更少。但是,当我运行代码时,结果是相反
public class MinMax {
public static void nonEfficient(int [] array){
int min=array[0],max=array[0];
for (int anArray : array) {
if (anArray < min)
min = anArray;
else {
if (anArray > max)
max = anArray;
}
}
System.out.println("Max is :" + max);
System.out.println("Min is :" + min);
}
public static void efficient(int [] arr,int length){
int max,min;
max = min = arr[0];
int i = 0;
for (; i < length / 2; i++)
{
int number1 = arr[i * 2];
int number2 = arr[i * 2 + 1];
if (arr[i * 2] >= arr[i * 2 + 1])
{
if (number1 > max)
max = number1;
if (number2 < min)
min = number2;
}
else
{
if (number2 > max)
max = number2;
if (number1 < min)
min = number1;
}
}
if (i * 2 < length)
{
int num = arr[i * 2];
if (num > max)
max = num;
if (num < min)
min = num;
}
System.out.println("***********************");
System.out.println("Max is :" + max);
System.out.println("Min is :" + min);
}
public static void main(String[] args) {
int [] array = new int[10000000];
Random rand = new Random();
for(int i=0;i<array.length;i++)
array[i] = rand.nextInt(100000)-144;
long startTime = System.currentTimeMillis();
nonEfficient(array); //theoretically non efficient 2n compares
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);// just 11ms
startTime = System.currentTimeMillis();
efficient(array, 10000000);///theoretically more efficient 1.5n compares
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);//whooping 37 ms..what happpened ????
}
}
公共类最小值{
公共静态无效无效(int[]数组){
int min=array[0],max=array[0];
for(整数数组:数组){
如果(数组<最小值)
最小值=无阵列;
否则{
如果(数组>最大值)
最大值=无阵列;
}
}
System.out.println(“最大值为:+Max”);
System.out.println(“最小值为:+Min”);
}
公共静态无效有效(int[]arr,int-length){
int max,min;
max=min=arr[0];
int i=0;
对于(;i=arr[i*2+1])
{
如果(编号1>最大值)
max=1号;
如果(数字2最大值)
max=数字2;
如果(1号<分钟)
最小=1号;
}
}
如果(i*2<长度)
{
int num=arr[i*2];
如果(数值>最大值)
max=num;
if(num 对于(int i=0;i,我将使用JDK进行重载:
Arrays.sort(array); // sort from lowest to highest
int min = array[0]; // the minimum is now the first element
int max = array[array.length - 1]; // and the maximum is last
您可以在3行中完成。除非处理大型阵列,否则这将非常有效。我将使用JDK来完成繁重的工作:
Arrays.sort(array); // sort from lowest to highest
int min = array[0]; // the minimum is now the first element
int max = array[array.length - 1]; // and the maximum is last
您可以在3行中完成。除非处理大型数组,否则这将非常有效。您的函数无效
不正确。如果使用[5,4,3,2,1]调用它
,将永远不会执行else
语句,并且max
将设置为Integer。最小值您的函数无效
不正确。如果使用[5,4,3,2,1]调用它
,将永远不会执行else
语句,max
将设置为Integer.MIN\u值
,让我们只计算比较:
for (int anArray : array) { // <- One: check array's border
if (anArray < min) // <- Two
min = anArray;
else {
if (anArray > max) // <- Three
max = anArray;
}
}
最后:N/2*9=4.5N
或者,如果优化器足够好,它可以消除5,6,但我们有
N/2 * 7 = 3.5N
您可以稍微改进代码
int min = array[array.length - 1];
int max = min; // <- there's no need to call array[array.length - 1]
// You can start from array.length - 2 not from usual array.length - 1 here
// Comparison with constant 0 is slightly better
// (one JZ or JNZ assembler instruction)
// than with array.length
for (int i = array.length - 2; i >= 0; --i) {
int v = array[i];
if (v > max)
max = v;
else if (v < min)
min = v;
}
int min=array[array.length-1];
int max=min;//让我们来计算比较:
for (int anArray : array) { // <- One: check array's border
if (anArray < min) // <- Two
min = anArray;
else {
if (anArray > max) // <- Three
max = anArray;
}
}
最后:N/2*9=4.5N
或者,如果优化器足够好,它可以消除5,6,但我们有
N/2 * 7 = 3.5N
您可以稍微改进代码
int min = array[array.length - 1];
int max = min; // <- there's no need to call array[array.length - 1]
// You can start from array.length - 2 not from usual array.length - 1 here
// Comparison with constant 0 is slightly better
// (one JZ or JNZ assembler instruction)
// than with array.length
for (int i = array.length - 2; i >= 0; --i) {
int v = array[i];
if (v > max)
max = v;
else if (v < min)
min = v;
}
int min=array[array.length-1];
int max=min;//如果您使用的是java8,那么可以采用流方法
在我看来,它在复杂的结构中更具可读性。
希望这对您有所帮助,如果您使用的是java8,您可以采用流方法
在我看来,它在复杂的结构中更具可读性。
希望这有助于在使用Java 8时,我不同意“不能变得更简单”这句话:
这段代码的性能不如您的,但考虑到您还获得了数组的计数和总数这一事实,它并没有那么差。这将您的代码与java8方法进行比较:
nonEfficient:
Max is :99855
Min is :-144
12
***********************
efficient:
Max is :99855
Min is :-144
43
***********************
java8:
Max is :99855
Min is :-144
69
在使用Java 8时,我不得不对“不能变得更简单”这句话持不同意见:
这段代码的性能不如您的,但考虑到您还获得了数组的计数和总数这一事实,它并没有那么差。这将您的代码与java8方法进行比较:
nonEfficient:
Max is :99855
Min is :-144
12
***********************
efficient:
Max is :99855
Min is :-144
43
***********************
java8:
Max is :99855
Min is :-144
69
试试这个:
if (length & 1)
{
// Odd length, initialize with the first element
min= max= a[0];
i= 1;
}
else
{
// Even length, initialize with the first pair
if (a[0] < a[1])
{
min= a[0]; max= a[1];
}
else
{
min= a[1]; max= a[0];
}
i= 2;
}
// Remaining pairs
while (i < length)
{
int p= a[i++], q= a[i++];
if (p < q)
{
if (p < min) min= p;
if (q > max) max= q;
}
else
{
if (q < min) min= q;
if (p > max) max= p;
}
}
if(长度&1)
{
//奇数长度,用第一个元素初始化
最小值=最大值=a[0];
i=1;
}
其他的
{
//偶数长度,使用第一对进行初始化
if(a[0]max)max=q;
}
其他的
{
如果(qmax)max=p;
}
}
您甚至可以使用这个丑陋的foreach循环摆脱数组索引,代价是布尔测试和额外的开销
// Initialize
min= max= a[0];
bool Even= true;
int p;
for (int q : a)
{
if (Even)
{
// Set p on hold
p= q;
}
else
{
// Process the pair
if (p < q)
{
if (p < min) min= p;
if (q > max) max= q;
}
else
{
if (q < min) min= q;
if (p > max) max= p;
}
}
Even= !Even;
}
if (!Even)
{
// Process the last element
p= a[length - 1];
if (p < min) min= p;
else
if (p > max) max= p;
}
//初始化
最小值=最大值=a[0];
布尔偶数=真;
INTP;
for(int q:a)
{
如果(偶数)
{
//让p暂停
p=q;
}
其他的
{
//处理这对
if(pmax)max=q;
}
其他的
{
如果(qmax)max=p;
}
}
偶数=!偶数;
}
如果(!偶数)
{
//处理最后一个元素
p=a[长度-1];
如果(pmax)max=p;
}
试试这个:
if (length & 1)
{
// Odd length, initialize with the first element
min= max= a[0];
i= 1;
}
else
{
// Even length, initialize with the first pair
if (a[0] < a[1])
{
min= a[0]; max= a[1];
}
else
{
min= a[1]; max= a[0];
}
i= 2;
}
// Remaining pairs
while (i < length)
{
int p= a[i++], q= a[i++];
if (p < q)
{
if (p < min) min= p;
if (q > max) max= q;
}
else
{
if (q < min) min= q;
if (p > max) max= p;
}
}
if(长度&1)
{
//奇数长度,用第一个元素初始化
最小值=最大值=a[0];
i=1;
}
其他的
{
//偶数长度,使用第一对进行初始化
if(a[0]max)max=q;
}
其他的
{
如果(qmax)max=p;
}
}
你甚至可以摆脱它