在不使用条件语句的情况下查找三个随机生成的数字中的最高、第二高和最低

Posted

技术标签:

【中文标题】在不使用条件语句的情况下查找三个随机生成的数字中的最高、第二高和最低【英文标题】:Find the highest, second highest, and lowest of three random generated numbers without using conditional statements 【发布时间】:2021-12-25 13:04:18 【问题描述】:

作为一名大学 IT 一年级学生,我有一个 Java 作业,我必须显示三个随机生成的数字,并按最高、第二高、最低的顺序排列它们。我们教授提出的挑战是不使用任何条件语句或数组。

代码如下:

import java.text.DecimalFormat;
import java.util.Scanner;
import java.util.Random;
public class Main 
  public static void main(String[] args) 
    DecimalFormat dcf = new DecimalFormat("0.00");
    Scanner sc = new Scanner(System.in);
    Random rand = new Random();
    int high, low, totnum;
    double NumAvr;
    
    high = 100;
    low = 1; 
     
    int a = (int)(Math.random()*(high-low+1)+low);  
    int b = (int)(Math.random()*(high-low+1)+low);  
    int c = (int)(Math.random()*(high-low+1)+low);   
    
    totnum = a + b + c;
    NumAvr = totnum / 3;
    
    System.out.println("The random grades are: "+a+", "+b+", "+c);
    System.out.println("====================================================");
    System.out.println("The highest number is: "+ Math.max(a, Math.max(b, c)));
    System.out.println("The second number is: "+ Math.max(b, c));
    System.out.println("The lowest number is: "+ Math.min(a, Math.min(b, c)));
    System.out.println("The average of three numbers is: "+dcf.format(NumAvr)+"%");
     

    //MathClass.java
  




我面临的问题是我正在努力获得最高和最低的“中间”值。是否有任何“中间”变量让我在不使用任何条件语句或数组的情况下获得第二高?

【问题讨论】:

如果不考虑int溢出,把它们全部相加,然后减去max和min。 @samabcde 75 到 100 之间的三个值;最大总和为 300。远低于 int 溢出。 @ElliottFrisch,为了安全起见。 【参考方案1】:

你可以这样做:

int max=Math.max(a, Math.max(b, c));
int min=Math.min(a, Math.min(b, c));
int inBetween=totnum - max -min:

【讨论】:

我猜这就是教授所追求的。【参考方案2】:

这是一种无需任何算术的方法。

int maximum(int a, int b, int c) 
    return Math.max(a, Math.max(b, c));


/**
 *  There are two conditions on the middle number. 
 *  1) It must not be maximum. The three Math.min s ensure this.
 *  2) Of the numbers which are not maximum, it should be the maximum.
 */
int middle(int a, int b, int c) 
    int minAb = Math.min(a, b);
    int minBc = Math.min(b, c);
    int minAc = Math.min(a, c);
    return maximum(minAb, minBc, minAc);

【讨论】:

【参考方案3】:

如果您可以第二次使用streams,您可以这样做:

int second = IntStream.of(a, b, c).sorted().skip(1).limit(1).findAny().getAsInt();

【讨论】:

【参考方案4】:

使用标准Math.min / Math.max 函数的问题在于它们使用了比较和三元运算符under the hood:

public static int max(int a, int b) 
    return (a >= b) ? a : b;

因此,如果本练习的目的是完全避免广义上的条件操作,则可以通过计算最小值和最大值来实现。

例如,在 C 中使用以下公式 may be used 来检测最大数量 max = (a > b) × b + (b > a) × a; 但在 Java 中不起作用,因为比较运算符会产生 boolean 值。

但是这种方法可以稍作修改,以便在计算两个数字之间的差时检查负号,并将符号转换为 1 表示负差 (a < b),否则使用位掩码和移位转换为 0 (a >= b)操作:

final int s = 0x80000000; // bit mask for sign
int min = (((a - b) & s) >>> 31) * a + (((b - a) & s) >>> 31) * b;
int max = (((a - b) & s) >>> 31) * b + (((b - a) & s) >>> 31) * a;

因此,对于三个随机输入值真正无条件按排序顺序打印它们的解决方案可能如下所示:

static void minMax(int a, int b, int c) 
    final int s = 0x80000000;
    System.out.print(a + ", " + b + ", " + c + " -> ");
    int min = (((a - b) & s) >>> 31) * a + (((b - a) & s) >>> 31) * b;
    int max = (((a - b) & s) >>> 31) * b + (((b - a) & s) >>> 31) * a;
    // or int max = a + b - min;
    
    min = (((min - c) & s) >>> 31) * min + (((c - min) & s) >>> 31) * c; 
    max = (((c - max) & s) >>> 31) * max + (((max - c) & s) >>> 31) * c;
    int mid = a - min + b - max + c;
    
    System.out.println(min + ", " + mid  + ", " + max);
    System.out.println("-----");

测试:

minMax(2, 3, 1);
minMax(2, 0, 6);
minMax(4, 2, -4);

输出:

2, 3, 1 -> 1, 2, 3
-----
2, 0, 6 -> 0, 2, 6
-----
4, 2, -4 -> -4, 2, 4
-----

【讨论】:

【参考方案5】:

totnuma + b + c。找到min,找到max。从totnum 中减去这是您的第二高值。此外,更喜欢在初始化变量时声明变量。 不要执行整数数学来求平均值。您可以使用printf 进行格式化。喜欢,

int high = 100;
int low = 75;
int a = (int) (Math.random() * (high - low + 1) + low);
int b = (int) (Math.random() * (high - low + 1) + low);
int c = (int) (Math.random() * (high - low + 1) + low);
int totnum = a + b + c;
System.out.printf("The random grades are: %d, %d, %d%n", a, b, c);
System.out.println("====================================================");
int highest = Math.max(a, Math.max(b, c));
int smallest = Math.min(a, Math.min(b, c));
int second = totnum - highest - smallest;
System.out.printf("The highest number is: %d%n", highest);
System.out.printf("The second number is: %d%n", second);
System.out.printf("The lowest number is: %d%n", smallest);
System.out.printf("The average of three numbers is: %.2f%%%n", totnum / 3.0);

示例输出

The random grades are: 87, 93, 89
====================================================
The highest number is: 93
The second number is: 89
The lowest number is: 87
The average of three numbers is: 89.67%

【讨论】:

非常感谢!

以上是关于在不使用条件语句的情况下查找三个随机生成的数字中的最高、第二高和最低的主要内容,如果未能解决你的问题,请参考以下文章

在不存在标识/增量的情况下插入递增的数字

(JFrame)如何在不显示的情况下读取随机数进行比较?

在不重复的范围内生成随机数

在不使用内置函数的情况下生成随机数 [关闭]

在不使用 iostream 的情况下保存 c++11 随机生成器的状态

如何在不替换条件的情况下随机化?