C語(yǔ)言實(shí)現(xiàn)統(tǒng)計(jì)100以?xún)?nèi)所有素?cái)?shù)的個(gè)數(shù)
本人C語(yǔ)言萌新,最近工作中頻頻出現(xiàn)C語(yǔ)言小錯(cuò)誤,遂決定使用笨方法提高我的C語(yǔ)言水平,堅(jiān)持每天一個(gè)C語(yǔ)言小練習(xí),養(yǎng)成C語(yǔ)言手感,從此讓編程成為習(xí)慣。
題目描述
統(tǒng)計(jì)100以?xún)?nèi)所有素?cái)?shù)的個(gè)數(shù)
分析
素?cái)?shù)(prime number)又稱(chēng)質(zhì)數(shù),在大于1的自然數(shù)中,除了1和它本身以外不再有其他因數(shù)的數(shù)稱(chēng)為質(zhì)數(shù),2是最小的素?cái)?shù)。
代碼實(shí)現(xiàn)
#include <stdio.h> #define INTEGER_RANGE 100 //數(shù)字范圍 int if_prime(int num); int main() { int sum = 0; /* 2是最小的素?cái)?shù),for循環(huán)范圍為2-100 */ for(int i = 2; i <= INTEGER_RANGE; i++) { if(if_prime(i)) sum++; } printf("%d以?xún)?nèi)的素?cái)?shù)個(gè)數(shù)為:%d\n", INTEGER_RANGE, sum); return 0; } /* * 判斷是否為素?cái)?shù),是則返回1,否返回0 * */ int if_prime(int num) { int i = 0; for(i = 2; i < num; i++) { /* 如果該數(shù)有存在1以外的其他正因數(shù),則不是素?cái)?shù) */ if(num % i == 0) return 0; } return 1; }
運(yùn)行結(jié)果
后期完善
這里只對(duì)if_prime(num)
函數(shù)進(jìn)行完善:
- 增加非法數(shù)字的判斷,
num
小于2直接返回0 - 將循環(huán)范圍由
2~num-1
改成2~sqrt(num)
至于為什么用sqrt
,這里借用下別人的解釋?zhuān)ū容^通俗易懂)
當(dāng)一個(gè)數(shù)不是素?cái)?shù)的時(shí)候,那這數(shù)肯定是除了它本身和1外的兩個(gè)數(shù)之積
( a*b = m )
,如果設(shè)a
是小于或者等于b
的數(shù),那a
肯定是小于等于m
的開(kāi)根,即a <= sqrt( m )
?!俣荣N吧(C語(yǔ)言吧)
還有一種用法是把num
改成num/2
,但是當(dāng)num
大于4時(shí),sqrt(num)
比num/2
小,所以用sqrt(num)
的效率比用num/2
高。
至于為什么可以用num/2
,這里也借用別人的解釋?zhuān)ㄓ悬c(diǎn)難懂)
其實(shí)這是數(shù)學(xué)知識(shí),n不除以2也行,只是運(yùn)算量更大,其實(shí)最少運(yùn)算量的方法是n開(kāi)根號(hào)。
我證明一下合理性吧。用反證法。
如果一個(gè)數(shù)是合數(shù),則一定能分解成兩個(gè)不是1的數(shù)相乘,所以能被分解成一個(gè)大于等于2的數(shù)和一個(gè)小于等于n/2相乘。
如果這個(gè)數(shù)沒(méi)有一個(gè)小于等于n/2的因數(shù),那它一定不是合數(shù),所以它一定是素?cái)?shù),不用再檢查后面的數(shù)了。這里是小于n/2,是因?yàn)槿绻@個(gè)數(shù)能被n/2整除,那2一定是它的因數(shù),很容易知道2小于等于n/2,所以在檢查n/2之前一定檢查過(guò)2。證明完成!
n開(kāi)根號(hào)也差不多這樣證明?!?a rel="external nofollow" target="_blank">https://fishc.com.cn/thread-181309-1-1.html
如果你對(duì)上面的兩種用法都不理解,那記住它們就行了。。。
#include <math.h> /* * 判斷是否為素?cái)?shù),是則返回1,否返回0(改進(jìn)版) * */ int if_prime(int num) { if(num < 2) return 0; //最小的素?cái)?shù)為2 int i = 0; //sqrt():開(kāi)方函數(shù)(一定要寫(xiě)小于等于) for(i = 2; i <= sqrt(num); i++) { /* 如果該數(shù)有存在1以外的其他正因數(shù),則不是素?cái)?shù) */ if(num % i == 0) return 0; } return 1; }
網(wǎng)上參考
原文鏈接:https://www.runoob.com/cprogramming/c-exercise-example36.html
sqrt()
為開(kāi)方函數(shù),需要加math.h
頭文件
// Created by www.runoob.com on 15/11/9. // Copyright ? 2015年 菜鳥(niǎo)教程. All rights reserved. // #include<stdio.h> #include<math.h> int main() { int i,j,k,n=0; for(i=2;i<=100;i++) { k=(int)sqrt(i); for(j=2;j<=k;j++) if(i%j==0) break; if(j>k) { printf("%d ",i); n++; if(n%5==0) printf("\n"); } } return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Visual Studio無(wú)法打開(kāi)源文件"stdio.h"問(wèn)題
這篇文章主要介紹了關(guān)于Visual Studio無(wú)法打開(kāi)源文件"stdio.h"問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04C++ STL入門(mén)教程(2) list雙向鏈表使用方法(附程序代碼)
這篇文章主要為大家詳細(xì)介紹了C++ STL入門(mén)教程第二篇,list雙向鏈表使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08C++通過(guò)CryptoPP計(jì)算Hash值的過(guò)程詳解
Crypto++ (CryptoPP) 是一個(gè)用于密碼學(xué)和加密的C++庫(kù),它是一個(gè)開(kāi)源項(xiàng)目,提供了大量的密碼學(xué)算法和功能,本文小編給大家介紹了C++通過(guò)CryptoPP計(jì)算Hash值的過(guò)程,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11c語(yǔ)言float類(lèi)型小數(shù)點(diǎn)后位數(shù)
在本篇文章里小編給大家整理了關(guān)于c語(yǔ)言float類(lèi)型小數(shù)點(diǎn)后面有幾位的相關(guān)知識(shí)點(diǎn),需要的朋友們可以學(xué)習(xí)下。2020-02-02C語(yǔ)言中字符串常用函數(shù)strcat與strcpy的用法介紹
以下是對(duì)C語(yǔ)言中字符串常用函數(shù)strcat與strcpy的使用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下2013-07-07