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();
}
}