我有一种情况,理论上总是会到达return嵌套在两个for循环中的语句.
编译器不同意并且需要return在for循环之外的语句.我想知道一种优雅的方法来优化这种方法,这超出了我目前的理解,并且我尝试的中断实现似乎都不起作用.
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
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ica 343
编译器的启发式方法永远不会让你省略最后一个return.如果你确定它永远不会到达,我会用a替换它throw以使情况清楚.
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");
}
Run Code Online (Sandbox Code Playgroud)
l0b*_*0b0 36
正如@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++;
}
}
Run Code Online (Sandbox Code Playgroud)
编译并运行良好.如果你得到一个,ArrayIndexOutOfBoundsException你就会知道实现在语义上是错误的,而不必明确地抛出任何东西.
Dav*_*ler 18
由于您询问了两个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;
}
Run Code Online (Sandbox Code Playgroud)
Sul*_*han 13
虽然断言是一个很好的快速解决方案.一般来说,这种问题意味着您的代码太复杂了.当我查看你的代码时,显然你并不真的想要一个数组来保存以前的数字.你想要一个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();
Run Code Online (Sandbox Code Playgroud)
现在请注意,我们返回的内容实际上是集合的大小.代码复杂度从二次变为线性,并且立即更具可读性.
现在我们可以意识到我们甚至不需要那个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();
Run Code Online (Sandbox Code Playgroud)
由于您的返回值基于外部循环的变量,您可以简单地将外部循环的条件更改为count < range,然后在函数末尾返回最后一个值(您刚刚省略):
private static int oneRun(int range) {
...
for (int count = 1; count < range; count++) {
...
}
return range;
}
Run Code Online (Sandbox Code Playgroud)
这样您就不需要引入永远无法访问的代码.
小智 5
使用临时变量,例如"result",并删除内部返回.使用适当的条件更改while循环的for循环.对我来说,只有一个返回作为函数的最后一个语句总是更优雅.
| 归档时间: |
|
| 查看次数: |
11200 次 |
| 最近记录: |