이론적으로는 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 루프를 변경하십시오. 나에게 함수의 마지막 문장으로 하나의 리턴만을 갖는 것이 항상 더 우아합니다.
답변
아마도 이것은 코드를 다시 작성해야 함을 나타냅니다. 예를 들면 :
- 정수 0 .. 범위 -1의 배열을 만듭니다. 모든 값을 0으로 설정합니다.
- 루프를 수행하십시오. 루프에서 난수를 생성합니다. 목록에서 해당 인덱스를보고 값이 1인지 확인하십시오. 만약 그렇다면 루프를 중단하십시오. 그렇지 않으면 해당 인덱스의 값을 1로 설정하십시오.
- 목록에서 1의 수를 세고 해당 값을 반환합니다.