在java中不使用条件语句检查肯定或否定

q35jwt9p  于 2023-01-24  发布在  Java
关注(0)|答案(8)|浏览(147)

上周有人问我一个面试问题:
我需要一个函数来打印出一个数字是正数还是负数,而不使用条件语句,如if elsewhileforswitcha? b:c等。我怎么做呢?
我告诉面试官这是不可能的,因为这个问题本质上是“有条件的”。他告诉我这是可能的,但没有告诉我怎么做。我做了相当多的搜索,但没有好的答案。

hpcdzsge

hpcdzsge1#

一个可能的解决方案是:

String[] responses = {"Positive", "Negative"};
System.out.println(responses[(i >> 31) & 1]);

这也将零计为正数。
因为Java中的整数需要存储在二进制补码中(或者表现得好像它们是)任何负数的最高位是1,任何其他数的最高位为0。(i >> 31)将最高位复制到每隔一位(因此负数变为11111111 11111111 11111111 11111111,而正数/零变为00000000 00000000 00000000 00000000)。& 1将除最低位之外的所有位设置为0。组合(i >> 31) & 1实际上只读取i的最高位。

hkmswyz6

hkmswyz62#

下面我们来详细解释一下immibis的回答:

int index(int i) {
    return 1 + (i>>31) - (-i>>31);
}

String[] text = {"negative", "zero", "positive"};

private String text(int i) {
    return text[index(i)];
}

带符号移位i>>31将每个负数转换为-1,将每个其他负数转换为0。计算-i>>31可以区分正数和非正数。现在来看计算的index

positive: 1 +    0 - (-1) = 2
zero:     1 +    0 -    0 = 1
negative: 1 + (-1) -    0 = 0
z6psavjg

z6psavjg3#

这里有一个变化,说明了零既不是正的也不是负的事实:

int x = (int)Math.sqrt(Math.pow(n, 2));
    try {
        x = n / x;
    }
    catch (ArithmeticException e) {
        x = 0;
    }

    String[] result = {"negative", "zero", "positive"};
    System.out.println(result[x + 1]);
cpjpxq1n

cpjpxq1n4#

超级简单的解决方案滥用了数组不能有负大小的事实:

void printPositive(int i) {
    try { new int[i]; System.out.println("positive"); } 
    catch( NegativeArraySizeException e) { System.out.println("negative"); }
}

好吧,如果i为正,这个答案可能会分配一个巨大的数组,VM在计算new int[i]时可能会使用条件语句,但至少它会向面试官展示某种创造力。这可能会向面试官表明你可以跳出思维定势(因为他可能会预料到你会像大多数其他答案使用的那样做一些小魔术),做一些完全不同的事情。

6jjcrrmo

6jjcrrmo5#

我给出这个新答案的原因是因为我使用了Boolean的compareTo方法,该方法使用三元运算符将布尔表达式转换为二进制。
这是我的新答案,更难读。

public static String positiveOrNegative(int n) {

    ArrayList<String> responses = new ArrayList<String>();
    // first element should be "Zero", so if n is 0, the response is "Zero"
    responses.add("Zero");

    // this populates the ArrayList with elements "Positive" for n elements
    // so that if n is positive, n will be an index in the ArrayList
    // and the return will be "Positive"
    // but still if n is negative, it will never be an index in the ArrayList
    for (int i = 0; i < n; i++) {
        responses.add("Positive");
    }

    String response = "";
    try {
        // try to get a response from the ArrayList
        response = responses.get(n);
    } catch (Exception e) {
         // index is out of bounds, so it must have been negative
        response = "Negative";
    }

    return response;
}

public static void main(String[] args) {
    System.out.println(positiveOrNegative(4)); // Positive
    System.out.println(positiveOrNegative(1)); // Positive
    System.out.println(positiveOrNegative(0)); // Zero
    System.out.println(positiveOrNegative(-1)); // Negative
    System.out.println(positiveOrNegative(-4)); // Negative
}
8hhllhi2

8hhllhi26#

另一种可能的解决方案:

boolean isPositive(int n) {
  return n > ((n + 1) % n);
}

但是它不适用于0
----编辑-----
新算法:

String isPositive(int n) {
  String[] results = {"-", "", "+"};
  return results[1+(1+((n+1)%n)*((n-1)%n))/n];
}

它仍然不适用于0

yb3bgrhw

yb3bgrhw7#

朋友们,这并不难,不需要移位或做奇怪的调用,只要使用Math类中的signum方法就行了。p

http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#signum%28float%29
rdlzhqv9

rdlzhqv98#

这是一个听起来很简单的问题,不使用条件句也是可能的;只需编写以下代码
System.out.println(n>0);

相关问题