Java 如何在不使用数组且仅使用三个比较器或比较的情况下找到4个输入中的第三大数

Java 如何在不使用数组且仅使用三个比较器或比较的情况下找到4个输入中的第三大数,java,algorithm,sorting,optimization,Java,Algorithm,Sorting,Optimization,我写的代码如下: /* Program to find the 3rd largest no from 4 nos without using arrays and only using 3 comparators or comparisons */ package d; public class thirdlargest { public static void main(String args[]) { in

我写的代码如下:

 /*
    Program to find the 3rd largest no from 4 nos without using arrays and
 only using 3 comparators or comparisons

     */
    package d;


    public class thirdlargest {
        public static void main(String args[]) {

           int a=1,b=2,c=3,d=4,soln;
           soln= Math.min(Math.max(a,b),Math.max(c,d));
           System.out.println("Third largest=" +soln);        
        }
    }
    /*
    Output:
    Third largest=2
     */

但这只适用于所使用的输入模式,如果我更改模式,输出将是错误的。如何通过仅使用3个比较器或严格的比较来修复此代码,并且我们可以使用任何编程语言

IMO仅使用三个比较无法找到4个数字中的第三大数字:

 public static void main(String[] args) throws IOException {
        int a=1,b=2,c=3,d=4,soln;
        int maximum1 = Math.max(a,b);
        int maximum2 = Math.max(c,d);

        if(maximum1 < maximum2) {
            // either c or d and we need more comparisons
        }
        else {
            // either a or b and we need more comparisons
        }
    }
publicstaticvoidmain(字符串[]args)引发IOException{
int a=1,b=2,c=3,d=4,soln;
int maximum1=数学最大值(a,b);
int max=Math.max(c,d);
如果(最大值1<最大值2){
//要么是c,要么是d,我们需要更多的比较
}
否则{
//要么是a要么是b,我们需要更多的比较
}
}
编辑:实际上,我们可以通过3次比较找到最大数或最小数,但可能不是第三大数等


同时检查此项,以查找
O(n)
时间内的第k个最大数字。

IMO仅使用三个比较无法找到4个数字中的第三大数字:

 public static void main(String[] args) throws IOException {
        int a=1,b=2,c=3,d=4,soln;
        int maximum1 = Math.max(a,b);
        int maximum2 = Math.max(c,d);

        if(maximum1 < maximum2) {
            // either c or d and we need more comparisons
        }
        else {
            // either a or b and we need more comparisons
        }
    }
publicstaticvoidmain(字符串[]args)引发IOException{
int a=1,b=2,c=3,d=4,soln;
int maximum1=数学最大值(a,b);
int max=Math.max(c,d);
如果(最大值1<最大值2){
//要么是c,要么是d,我们需要更多的比较
}
否则{
//要么是a要么是b,我们需要更多的比较
}
}
编辑:实际上,我们可以通过3次比较找到最大数或最小数,但可能不是第三大数等

还可以检查此项以查找
O(n)
时间中的第k个最大值。

在Math StackExchange网站上讨论了查找n个值中第二大值的问题。它声明(有证据)下(紧)界为N+上限(log2N)-2

对于N==4,其计算结果为4

(这在这里适用,因为4中的第三大也是4中的第二小。)

我不认为证明排除了(假设的)少于4个比较的解决方案,这些比较依赖于N个数是唯一的。但这并不是问题陈述的一部分。

在Math StackExchange网站上讨论了查找N值中第二大值的问题。它声明(有证据)下(紧)界为N+上限(log2N)-2

对于N==4,其计算结果为4

(这在这里适用,因为4中的第三大也是4中的第二小。)


我不认为证明排除了(假设的)少于4个比较的解决方案,这些比较依赖于N个数是唯一的。但这不是问题陈述的一部分。

我不确定“comparator”的确切定义是什么,以及他们使用它的方式。但是假设
Math.min
Math.max
不算作比较器,这里有一种不使用比较或比较器计算的方法:

public static int thirdLargest(int a, int b, int c, int d) {
    int min = Math.min(a, Math.min(b, Math.min(c,d)));
    int offset = min + 1 - Integer.MIN_VALUE;
    a -= offset;
    b -= offset;
    c -= offset;
    d -= offset;
    min = Math.min(a, Math.min(b, Math.min(c,d)));
    return min + offset;
}
计算第三大数与计算第二小数相同。这段代码的诀窍是,它计算最小的数字,然后从每个数字中减去使最小数字环绕并成为Integer.MAX_值所需的精确偏移量,而不环绕其他值。剩下的最小的数字现在是原始数字的第二个最小值,减去偏移量,我们再加回去

然而,我承认,只有当所有四个数字都是不同的——或者,至少,如果最低的两个数字是不同的,这才有效。如果你给它a=1,b=1,c=2,d=3,它就会失败——它输出2而不是1。至少这会让你在解决问题的能力上得到分数,这也是我假设这个问题的目的。最好不要弄清楚在生产环境中如何实际解决这个问题,因为对生产代码(没有数组)施加这样的限制是愚蠢的

编辑:

这是另一个解决方案。代码中有一个比较,但是它在一个执行了三次的方法中,所以应该算作三个比较

public static int thirdLargest(int a, int b, int c, int d) {
    if (isThirdLargest(a, b, c, d)) {
        return a;
    }
    if (isThirdLargest(b, a, c, d)) {
        return b;
    }
    if (isThirdLargest(c, a, b, d)) {
        return c;
    }
    return d;
}

public static boolean isThirdLargest(int a, int b, int c, int d) {
    int z = 3 + ((b - a) >> 31) + ((c - a) >> 31) + ((d - a) >> 31);
    // z = number of other parameters that are >= a.  Note that all of the
    // shift operations will return either 0 or -1.
    int y = 3 + ((a - b) >> 31) + ((a - c) >> 31) + ((a - d) >> 31);
    // y = number of other parameters that are <= a
    int x = -y >>> 31;
    // x = 1 if there are any other parameters <= a, 0 if not.  Note that
    // x can be 0 only if z == 3.
    int w = z & (x << 1);
    // This will be 2 if a is the third largest.  If z == 2, then x == 1
    // and w will be 2.  If z == 3, and x == 1, that means that a is the
    // smallest but is equal to at least one of the other parameters;
    // therefore a is also the third largest.  But if x == 0, a is
    // strictly smaller than all other parameters and is therefore not the
    // third largest.
    return w == 2;
}
publicstaticintthirdlargest(inta、intb、intc、intd){
if(第三大(a、b、c、d)){
返回a;
}
if(第三大(b、a、c、d)){
返回b;
}
if(第三大(c、a、b、d)){
返回c;
}
返回d;
}
公共静态布尔isThirdLargest(int a、int b、int c、int d){
intz=3+((b-a)>>31+((c-a)>>31+((d-a)>>31);
//z=>=a的其他参数的数量。请注意,所有
//换档操作将返回0或-1。
int y=3+((a-b)>>31)+((a-c)>>31)+((a-d)>>31);
//y=大于31的其他参数的数量;

//x=1如果有任何其他参数我不确定“comparator”的确切定义,以及它们的使用方式。但是假设
Math.min
Math.max
不算作比较器,这里有一种不使用比较或比较器计算的方法:

public static int thirdLargest(int a, int b, int c, int d) {
    int min = Math.min(a, Math.min(b, Math.min(c,d)));
    int offset = min + 1 - Integer.MIN_VALUE;
    a -= offset;
    b -= offset;
    c -= offset;
    d -= offset;
    min = Math.min(a, Math.min(b, Math.min(c,d)));
    return min + offset;
}
计算第三大数与计算第二小数相同。这段代码的诀窍在于,它计算最小数,然后从每个数中减去使最小数环绕并变为Integer.MAX_值所需的精确偏移量,而不环绕其他值。最小的剩下的数字现在是原始数字的第二个最小值,减去偏移量,我们再加回去

然而,我承认,这只在四个数字都不同的情况下才有效——或者,至少,如果最低的两个数字是不同的。如果你给它a=1,b=1,c=2,d=3,它会输出2而不是1。至少这会让你的问题解决技能得分,这是我假设问题的目的。它最好r不是f
public class thirdlargest 
{
    public static void main(String args[]) 
    {
        System.out.println("Third highest number: " + thirdHighest(1, 2, 3, 4));     
        System.out.println("Third highest number: " + thirdHighest(4, 3, 2, 1));  
        System.out.println("Third highest number: " + thirdHighest(-5, -4, -3, -2));  
        System.out.println("Third highest number: " + thirdHighest(0, 0, 0, 0));  
    }

    private static int thirdHighest(int a, int b, int c, int d)
    {
        int testa = a, testb = b, testc = c, testd = d;

        int divisionResult;
        int numberFound = 0;

        while(true)
        {             
            try
            {
                divisionResult = 1 / (testa++ - Integer.MAX_VALUE); 
            }
            catch(Exception ex)
            {
                numberFound++;
                if(numberFound == 2)
                {
                    return a;
                }
            }

            try
            {
                divisionResult = 1 / (testb++ - Integer.MAX_VALUE); 
            }
            catch(Exception ex)
            {
                numberFound++;
                if(numberFound == 2)
                {     return b;
                }
            }

            try
            {
                divisionResult = 1 / (testc++ - Integer.MAX_VALUE); 
            }
            catch(Exception ex)
            {
                numberFound++;
                if(numberFound == 2)
                {
                    return c;
                }
            }

            try
            {
                divisionResult = 1 / (testd++ - Integer.MAX_VALUE); 
            }
            catch(Exception ex)
            {
                numberFound++;
                if(numberFound == 2)
                {
                    return d;
                }
            }
         }
    }
}
import java.util.Scanner;

public class TmaxFourNo {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter no.'s:");
        int w = sc.nextInt();
        int x = sc.nextInt();
        int y = sc.nextInt();
        int z = sc.nextInt();
        int m1 = Math.min(Math.max(w, x), Math.max(y, z));
        int m2 = Math.max(Math.min(w, x), Math.min(y, z));
        if (m1 < m2) {
            System.out.println("Tmax=" + m1);
        } else {
            System.out.println("Tmax=" + m2);
        }
        sc.close();

    }

}