两天一题-LeetCode-质数的个数

6 篇文章 0 订阅
6 篇文章 0 订阅

两天一题系列:
准备鞭策自己瞎做个两天一题系列,关于每题写一篇感悟和理解。

题目:
摘自LeetCode。
判断给定数中质数的个数,并返回int值,其值为质数的个数。

知识点:

  1. 循环语句。(历遍小于给定数的每个数)
  2. 判断。(判断历遍小于给定数的每个数中是否存在合数)

困难:
A-想按照思路实现时语句总出现问题。
B-跑程序找不到Bug原因。

思路:

  1. 找出质数的特征。
    质数:只能被1和它本身除即为质数。
    (且判断输入数是否为正数,负数直接?有必要么?没有必要判断给定数是否为负数)

  2. 双循环。
    A-第一层循环将给定数n从2开始,依次往上加,直到循环数等于给定数n。历遍小于给定数的每一个数。
    B-第二层循环在第一层循环中,
    且将第一层循环数依次除以2、3、5、7.一旦取余的数为0,则跳出第二层循环,第二层循环停止条件为:第二层循环数等于第一层循环数。当第二层循环结束,质数的个数加一。
    以上思路有问题,即使不能被2、3、5、7整除仍有可能被13、17等数整除,因此第二层循环需从2开始,当历遍的某数能被第二层循环中数整除,即取余为0,则判定第一层循环中的历遍数为合数。
    第二层循环停止条件为第二层循环数<第一层循环历遍数。

以上。

代码表示为:

class Solution {    public int countPrimes(int n) {    
int i = 0,j = 0;    
int k = 0;    
int a;
    switch(n){        
	case 1:          
		i = 0;          
		return i;        
	case 2:          
	   	i = 0;          
	    	return i;        
        default:            
  		for(j = 2;j < n;j++){                
 			 for(k = 2,a = 0;k <= j;k++){                    
  				if(k%j == 0){                       
  					a++;                       
				        break;                    
 					    }else{                        
  						continue;                    
 						 }                
   					     }                
 		 switch(a){                    
  			case 0:                      
 		        i++;                      
  			break;                
  			}            
 		 }        
  	 }    
  	  return i;
        }
}

总结:
程序没跑出来。
A-结果:无论输入什么数输出都是
B-猜想:一定进入某一循环或者一遇到某条件直接为0,且不清楚break与continue的差别。
C-仍需测试。

——————————————————————————————————

以下:2019/11/23重新调试
易错点:
1 JAVA中取余为运算符%,取整为运算符/。
2 循环中break与continue的差别,若同时存在双层循环,break是跳出两层循环,还是仅仅跳出它所在的那一层循环?

调试思路:
A先调试3的质数的结果,按照原思路,在eclipse中添加输入语句,判断程序是否进入这一段循环等。
B写出另一个程序,先找到判断质数的方法。
如指定数为4,判断4是否为质数。
思路:历遍4中的每一个数判断其中是否存在能被4整除的数,若存在能被整除的数(除1与它本身),则返回false;若不存在,则返回true.

static boolean getOnePrimeIf(int primeOne) {
  //判断某数primeOne(primeOne<prinme)是否为质数,是返回true,不是返回false
  boolean a = true;
  int i;//历遍循环数。
   for(i = 2;i < primeOne;i++) {
//只要出现了第一个能被整除的数,除1外,i从2开始,则判定该数为合数
	    if(primeOne%i == 0) {
	     a = false;
	     System.out.println("执行"+(i-1)+"次"+primeOne%i);
	     return a;
	    }else {
	     System.out.println("执行"+(i-1)+"次");
	     continue;
	    }
	   }
	  return a;
 }

多次测试后,该程序可以顺利判断某给定数是否为质数。以下附上测试结果,判断169及13是否为质数。
在这里插入图片描述
C 第二层循环可按照步骤B中所述。需要改动的是,将返回boolean值替换为int值,若是质数则返回1,若不是质数则返回0。
上一段代码错误原因为:当内层循环判断了出现合数时,直接跳出内层循环,不进行质数相加,因此进入不了default中的switch。
以下附上代码:

static int howMuch(int primeThree) {//返回某数中质数的个数
  int a = 0;
  int b = -1;
  //按照道理只要第一道循环中历遍做好就好。
  int j,i;//第一个循环数和第二个循环数
   for(j = 2;j < primeThree;j++) {
    //从2开始历遍指定数,直到小于指定数,对历遍数做是否为质数的判断
    System.out.println("j:"+j);
    for(i = 2;i < j;i++) {
     //历遍的该数进入此循环,为质数则a+1
     System.out.println("i:"+i+"a:"+a);
     if(j%i == 0) {
      a++;//合数
      System.out.println("a:"+a);
      System.out.println("if:"+j+"%"+i+"-"+j%i);
      break;//break之后不会在第一层循环中计数了
     }else {
      System.out.println("else:"+j+"%"+i+"-"+j%i);
      continue;
      //这个质数的+1应该放在哪?
     }
    }
   }
   System.out.println("最终循环中合数的个数为:"+a);
   b += primeThree-a;
  return b-1;
 }

有点啰嗦,为了知道代码从哪个步骤走,我每一步都添加了打印输出。
思路:
内层循环采用上面测试成功的能判断是否为质数的程序,外层循环仅历遍给定数中从2到(给定数-1)。但质数的增加比较难做到,一旦内层循环判断给定数中某数为合数,则直接跳出该循环,无法执行加1的步骤。因此,一旦判断出该数为合数,则计合数+1,最终返回的质数为给定数-合数的个数(且由于2的特殊性,将最终回的质数个数额外-1即可)。

结论:
力扣中程序不正确,超出时间限制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值