[java] Java 메소드에서 쓸모없는 반환을 피하려면 어떻게해야합니까?

이론적으로는 return두 개의 for루프에 중첩 된 문에 항상 도달 하는 상황이 있습니다.

컴파일러는 동의하지 않으며 루프 return외부의 명령문이 필요합니다 for. 현재의 이해를 뛰어 넘는이 방법을 최적화하는 우아한 방법을 알고 싶습니다. 시도한 break 구현 중 어느 것도 작동하지 않는 것 같습니다.

Attached는 임의의 정수를 생성하고 int 매개 변수로 메서드에 전달 된 범위 내에서 생성 된 두 번째 임의의 정수를 찾을 때까지 순환되는 반복을 반환하는 할당의 메서드입니다.

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) { // Run until return.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                return count;
            }
        }
    }
    return 0; // Never reached
}



답변

컴파일러의 휴리스틱은 마지막 return. 절대 도달 할 수 없다고 확신한다면 throw상황을 명확히하기 위해 a 로 교체하겠습니다 .

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) {
        ...
    }

    throw new AssertionError("unreachable code reached");
}


답변

으로 @BoristheSpider 지적 당신은 확실히 두 번째 할 수 있습니다 return문이 의미에 도달 할 수 있습니다 :

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    int count = 0;

    while (true) {
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                return count;
            }
        }
        count++;
    }
}

잘 컴파일 및 실행됩니다. 그리고 만약 당신이 ArrayIndexOutOfBoundsException어떤 것을 명시 적으로 던질 필요없이 구현이 의미 적으로 잘못되었음을 알게 될 것입니다.


답변

두 개의 for루프를 분리하는 것에 대해 질문 했으므로 레이블을 사용하여 수행 할 수 있습니다 (아래 예제 참조).

private static int oneRun(int range) {
    int returnValue=-1;

    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    OUTER: for (int count = 1; count <= range; count++) { // Run until return.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.   
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                returnValue = count;
                break OUTER;
            }
        }
    }
    return returnValue;
}


답변

단언은 좋은 빠른 해결책입니다. 일반적으로 이런 종류의 문제는 코드가 너무 복잡하다는 것을 의미합니다. 코드를 볼 때 배열이 이전 숫자를 보유하는 것을 원하지 않는 것이 분명합니다. 당신은 원하는 Set:

Set<Integer> previous = new HashSet<Integer>();

int randomInt = generator.nextInt(range);
previous.add(randomInt);

for (int count = 1; count <= range; count++) {
    randomInt = generator.nextInt(range);
    if (previous.contains(randomInt)) {
       break;
    }

    previous.add(randomInt);
}

return previous.size();

이제 우리가 반환하는 것은 실제로 세트의 크기입니다. 코드 복잡성이 2 차에서 선형으로 감소했으며 즉시 더 읽기 쉽습니다.

이제 우리는 해당 count인덱스 가 필요하지 않다는 것을 알 수 있습니다 .

Set<Integer> previous = new HashSet<Integer>();

int randomInt = generator.nextInt(range);

while (!previous.contains(randomInt)) {
    previous.add(randomInt);
    randomInt = generator.nextInt(range);
}

return previous.size();


답변

반환 값은 외부 루프의 변수를 기반으로하므로 외부 루프의 조건을 변경 count < range한 다음 함수 끝에서이 마지막 값 (방금 생략)을 반환 할 수 있습니다.

private static int oneRun(int range) {
    ...

    for (int count = 1; count < range; count++) {
        ...
    }
    return range;
}

이렇게하면 도달 할 수없는 코드를 도입 할 필요가 없습니다.


답변

예를 들어 “result”와 같은 임시 변수를 사용하고 내부 반환을 제거합니다. 적절한 조건으로 while 루프에 대한 for 루프를 변경하십시오. 나에게 함수의 마지막 문장으로 하나의 리턴만을 갖는 것이 항상 더 우아합니다.


답변

아마도 이것은 코드를 다시 작성해야 함을 나타냅니다. 예를 들면 :

  1. 정수 0 .. 범위 -1의 배열을 만듭니다. 모든 값을 0으로 설정합니다.
  2. 루프를 수행하십시오. 루프에서 난수를 생성합니다. 목록에서 해당 인덱스를보고 값이 1인지 확인하십시오. 만약 그렇다면 루프를 중단하십시오. 그렇지 않으면 해당 인덱스의 값을 1로 설정하십시오.
  3. 목록에서 1의 수를 세고 해당 값을 반환합니다.