简体   繁体   English

将if / else块转换为三元运算符时的错误答案

[英]wrong answer when converting if/else block to ternary operator

I am trying to convert my java code from if/else block to ternary operator. 我正在尝试将Java代码从if / else块转换为三元运算符。

What my code is doing is finding the position of an array at which all values of integers have occured already for example, 我的代码正在做的事情是找到一个数组的位置,在该位置已经出现了所有整数值,例如,

if array is {1,1,3,4,2,3,4,5,1,4} 如果数组是{1,1,3,4,2,3,4,5,1,4}

the answer would be 7 because by the time my program iterated to 7th position, it already found all previous numbers less than 5. 答案是7因为到我的程序迭代到7th位时,它已经发现所有以前的数字都小于5。

if array is {3,1,1,2,1,3} the answer would be 3 because by the time my program iterated to 3 position of the array, it had already iterated all values that are less than 3 . 如果array为{3,1,1,2,1,3} ,答案将为3因为到我的程序迭代到数组的3位置时,它已经迭代了所有小于3值。

Now, my code is working fine when I am using if/else block. 现在,当我使用if / else块时,我的代码工作正常。

this is the code that is working absolutely fine for me, 这是对我来说绝对正常的代码,

public static int solution1 (int arrayMaxValue, int[] myArray){

    boolean b[] = new boolean[arrayMaxValue + 1];
    for (int i = 0; i < myArray.length; i++) {
        if (!b[myArray[i]]){
            b[myArray[i]] = true;
            if (b[myArray[i]]==true)
                arrayMaxValue--;
        }
        if (arrayMaxValue==0) return i;
    }
    return -1;
}

but if i convert its if block to ternary operator ? 但是如果我将其if块转换为ternary operator ?

it gives the wrong output, 它给出了错误的输出,

public static int solution2 (int arrayMaxValue, int[] myArray){
        boolean b[] = new boolean[arrayMaxValue + 1];
        for (int i = 0; i < myArray.length; i++) {


            b[myArray[i]] = (!b[myArray[i]]) ? true : false;
            if (b[myArray[i]]){
                arrayMaxValue--;
            }


            if (arrayMaxValue==0) return i;
        }
        return -1;
    }

This is how i checked it, 这就是我检查的方式

    int[] myArray = { 1,1,1,2,3,4,1 };
    // _ _ _ _ _
    int arrayMaxValue =4;

    System.out.println(solution1(arrayMaxValue, myArray));
    System.out.println("==============================");
    System.out.println(solution2(arrayMaxValue, myArray));

The output of the above array should be 5 because by the time the loop iterated to position 5, all values less than or equals to 4 were spotted, the first solution gives the right answer but the second doesn't. 上面的数组的输出应该为5因为当循环迭代到位置5时,发现了所有小于或等于4值,第一个解决方案给出了正确的答案,而第二个解决方案却没有。

here is the output from both solution for the above array, 这是上述数组的两个解决方案的输出,

5
==============================
4

what am I doing wrong in ternary operator ? 三元运算符在做什么?

In your ternary operator version you are decrementing arrayMaxValue if b[myArray[i]] is true after the ternary operator is executed, and the ternary operator negates the value of b[myArray[i]] . 在您的三元运算符版本中,如果在执行三元运算符后b[myArray[i]]为true,则递减arrayMaxValue ,并且三元运算符取反b[myArray[i]]

b[myArray[i]] = (!b[myArray[i]]) ? true : false;

is the same as 是相同的

b[myArray[i]] = !b[myArray[i]];

In the original version you are decrementing arrayMaxValue only if b[myArray[i]] changes from false to true, and you never change b[myArray[i]] from true to false. 在原始版本中,仅当b[myArray[i]]从false更改为true时,才减小arrayMaxValue ,并且永远不要将b[myArray[i]]从true更改为false。

I don't think the ternary operator is useful in your code, since your condition does more than simply assigning a value to b[myArray[i]] based on a condition - it also has the side effect of decrementing arrayMaxValue . 我认为三元运算符在您的代码中没有用,因为您的条件不仅可以根据条件为b[myArray[i]]分配值,而且还具有减少arrayMaxValue You can simplify your code this way : 您可以通过以下方式简化代码:

if (!b[myArray[i]]) {
    b[myArray[i]] = true;
    arrayMaxValue--;         
}

In order for the ternary operator to assign the same value to b[myArray[i]] as your original code it should be : 为了使三元运算符为b[myArray[i]]分配与原始代码相同的值,它应该是:

b[myArray[i]] = (!b[myArray[i]]) ? true : b[myArray[i]];

(which is a complicated way to write b[myArray[i]] = true; ) (这是写b[myArray[i]] = true;一种复杂方法)

but arrayMaxValue-- will be executed also when b[myArray[i]] was and stayed true, which is different from the logic of the original implementation. 但是arrayMaxValue--也将在b[myArray[i]]并保持为true时执行,这与原始实现的逻辑不同。

This is not code I recommend. 不是我建议的代码。 Your function is far cleaner and more readable using if/else than this way. 使用if / else可以比这种方式更简洁,更易读。 I see this mainly as a demonstration of why one should usually ignore ?: . 我主要是为了说明为什么通常应该忽略?:

However, taking it as a challenge to rewrite your function using only ?: ... 但是,仅使用?: ...来重写函数是一个挑战。

  public static int solution3(int arrayMaxValue, int[] myArray) {
    int result = -1;
    boolean b[] = new boolean[arrayMaxValue + 1];
    for (int i = 0; i < myArray.length && result == -1; i++) {
      arrayMaxValue = b[myArray[i]] ? arrayMaxValue : arrayMaxValue - 1;
      b[myArray[i]] = true;
      result = (arrayMaxValue == 0) ? i : result;
    }
    return result;
  }

The main thing to remember is that, if you don't want to change the left hand side of the assignment of a ?: result you can use its old value as one of the alternatives. 要记住的主要事情是,如果您不想更改?:结果的左侧,则可以将其旧值用作替代方法之一。

In the previous answer Eran states correctly that the ternary operator you used is just a complex way to write b[myArray[i]] = !b[myArray[i]]; 在先前的答案中,Eran正确地指出,您使用的三元运算符只是编写b[myArray[i]] = !b[myArray[i]];一种复杂方法b[myArray[i]] = !b[myArray[i]]; In the comments to Eran's anwer you noted that your task was 在对伊兰答案的评论中,您指出您的任务是

to design this program using if/else and ternary operator both 使用if / else和三元运算符设计该程序

It is surely possible to use the ternary operator. 当然可以使用三元运算符。 You just need to use the operator to assign some other value. 您只需要使用运算符来分配其他值。 Eg the value for arrayMaxValue : 例如, arrayMaxValue的值:

for (int i = 0; i < myArray.length; i++) {
  arrayMaxValue -= b[myArray[i]] ? 0 : 1;
  b[myArray[i]] = true;
  if (arrayMaxValue==0) return i;
}

In this code you will use the ternary operator to decide whether you decrement the arrayMaxValue by 1 (if b[myArray[i]] is false ) or not (if b[myArray[i]] is true we will decrement it by 0). 在这段代码中,您将使用三元运算符来决定是否将arrayMaxValue减1(如果b[myArray[i]]false )(如果b[myArray[i]]true我们将其减0)。 。

PS Note that the b[myArray[i]] value is always set to true in each iteration of your cycle. PS注意, b[myArray[i]]值在循环的每次迭代中始终设置为true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM