写程序要细心,遇到bug要善于排查。
今天在用Java写几个小程序的时候,由于极力追求优化与功效,忽视了一个小小的细节问题。但最终找到了bug并且解决了它。
我们都知道,在使用for循环的时候,比如:
for(int i = 0; i < n; i++){...}
我们一般都这儿写。但是仅仅这样是不够的,因为这段语句还可以进行优化。比如i<n,就不如直接判断i!=n,这样在计算机内部可以节省运算时间。还有,i++还可以改写成++i,因为i++需要计算机保存i之前的值之后再+1,++i直接让i+1并没有临时变量。可是,正因为如此,一个小小的不易察觉的bug发生了。
原题目很简单,就是求整数a,b之间的全部素数。开始我是这么写的:
import java.io.*; import java.util.*; public class number2 { public static void main(String[] args) throws IOException{ int begin, end; String str; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); str = br.readLine(); begin = new Integer(str); BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in)); str = br1.readLine(); end = new Integer(str); for (; begin != end; ++begin){ boolean b = true; for(int i = 2; i != Math.sqrt(begin); ++i){ if(0 == begin % i){ b = false; break; } } if(b) System.out.println(begin); } } }
注意仔细看代码着色部分,乍看之下没什么不对,追求了性能。可是运算的结果却是令人大吃一惊。求101到200的素数,出现121,169两个数。经过我仔细排查之后发现原来bug正是出在这里:Math.sqrt()是double,i是一个int,在与double的比较过程中是永远不相等的。或者我们把着色语句强制转换成(int),或者,改写成 i<Math.sqrt(begin)。
修改之后成功运行,代码如下:
1 import java.io.*; 2 import java.util.*; 3 public class number2 { 4 public static void main(String[] args) throws IOException{ 5 int begin, end; 6 String str; 7 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 8 str = br.readLine(); 9 begin = new Integer(str); 10 BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in)); 11 str = br1.readLine(); 12 end = new Integer(str); 13 for (; begin != end; ++begin){ 14 boolean b = true; 15 for(int i = 2; i < Math.sqrt(begin); ++i){ 16 if(0 == begin % i){ 17 b = false; 18 break; 19 } 20 } 21 if(b) 22 System.out.println(begin); 23 } 24 } 25 }
关于代码中出现的输入输出流以后再做讨论。
时间: 2024-12-17 21:53:10