循环结构
1、最大公约数与最小公倍数
题解:
(1)求最大公约数
递归:
//最大公约数 = 小数 与 (大数%小数) 的最大公约数
//若a<b,经过一次辗转相除后,a,b的值会互换,所以不需要考虑a,b谁大
int gcd(int a,int b){
if(a%b == 0){
return b; }
else{
gcd(b,a%b);
}
}
非递归:
//辗转相除法
int gcd(int a,int b){
int r = 0;
while(b!=0){
r = a%b;
a = b;
b = r;
}
return a;
}
(2)求最小公倍数
// a*b==(a,b的最大公约数)*(a,b的最小公倍数)
int lcm(int a,int b){
int gcd = gcd(a,b);
return a*b/gcd;
}
完整代码:
#include<stdio.h>
int gcd(int a,int b);
int fun2(int a,int b);
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d %d",gcd(a,b),fun2(a,b));
return 0;
}
/*递归求最大公约数 */
int gcd(int a,int b){
if(a%b == 0){
return b;
}else{
gcd(b,a%b);
}
}
/*最大公约数*最小公倍数=a*b*/
int fun2(int a,int b){
int max,min;
min = gcd(a,b);
max = a*b/min;
return max;
}
2、字符串分类统计
解题思路与注意事项:
(1)输入一行字符串
//定义字符数组 引入头文件
include"string.h"
char str[1000];
gets(str);
// 调用字符输入函数
char e;
while((e = getchar()) != '\n'){
...
}
(2)字符分类
// 根据ASCII码来分类
while((e=getchar())!='\n')
{
if(65<=e && e<=90 || 97<=e && e<=122)
a++; //遇到字母字符 a自增
else if(48<=e && e<=57)
b++; //遇到数字字符 b自增
else if(e==32)
c++; //遇到空格字符 c自增
else
d++; //遇到其他字符 d自增
}
printf("%d %d %d %d\n",a,b,c,d); //注意题目的输出数字每个都隔了一个空格
//根据 字符直接区分
#include<stdio.h>
int main()
{
int letter = 0,number = 0,blank = 0,others = 0,c; //分别为字母、数字、空格、其他
while((c = getchar()) != '\n'){
if(c >= 'A' && c<='Z' || c >= 'a' && c <= 'z') //判断是否为字母
letter++;
else if(c >= '0' && c <= '9') //判断是都为数字
number++;
else if(c == ' ') //判断是否为空格
blank++;
else //其他
others++;
}
printf("%d %d %d %d\n",letter,number,blank,others);
return 0;
}
// 调用库函数
#include<stdio.h>
int main()
{
int letter = 0,number = 0,blank = 0,others = 0,c; //分别为字母、数字、空格、其他
while((c = getchar()) != '\n'){
if(c >= 'A' && c<='Z' || c >= 'a' && c <= 'z') //判断是否为字母
letter++;
else if(c >= '0' && c <= '9') //判断是都为数字
number++;
else if(c == ' ') //判断是否为空格
blank++;
else //其他
others++;
}
printf("%d %d %d %d\n",letter,number,blank,others);
return 0;
}
3、Sn的公式求和
题解:
注意:Sn需要两次累加
//正确
#include<stdio.h>
#include<math.h>
int main()
{
int n;
int Sn = 0;
int temp = 0;
scanf("%d",&n);
for(int i = 0;i < n;++i){
temp += 2*pow(10,i);
Sn +=temp;
}
printf("%d",Sn);
return 0;
}
//错误:
#include<stdio.h>
#include<math.h>
int main()
{
int n;
int Sn = 0;
int temp = 0;
scanf("%d",&n);
for(int i = 0;i < n;++i){
Sn +=2*pow(10,i);;
}
printf("%d",Sn);
return 0;
}
// 该结果为:22222,相当于没有累加,每次改变的是变量temp值,需要将改变后的temp值累加,所以需要两次
4、阶乘求和
题解:注意变量范围定义,否则溢出!!!
#include<stdio.h>
#include<math.h>
int main()
{
long long Sn = 0;
int n;
scanf("%d",&n);
for(n;n>0;--n){
long long temp = 1;//中间变量也需要定义为long long
for(int i = n;i>0;--i){
temp *=i;
}
Sn += temp;
}
printf("%lld",Sn);
return 0;
}
5、完数的判断
解题思路:
(1)循环遍历满足完数条件的所有完数用 i 存储;
(2)对于完数 i 的所有因子用 数组a 存储,且数组长度为count;
(3)每次新的完数需要更新中间变量temp 和 数组a,以及count。
#include<stdio.h>
#include<math.h>
int main()
{
int N;
int a[100];
scanf("%d",&N);
for(int i = 6;i < N; i=i+2){
int temp = 0;
int count = 0;
int k = 0;
for(int j = 1;j < i;++j){
if(i % j == 0){
temp += j;
count++;
a[k++] = j;
}
}
if(temp == i){
printf("%d its factors are ",i);
for(int m = 0;m < count;++m){
printf("%d ",a[m]);
}
printf("\n");
}
}
return 0;
}
6、迭代法求平方根
解题思路:
迭代法迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程。
要灵活运用迭代法思维,本题就是先让x=(1+4/1)/2=2.5;然后第二次x=(2.5+4/2.5)/2=2.05。。。如此下去就会越来越接近2是不是!就跟开方一样。直到最后进度满足了就退出循环。
#include<stdio.h>
#include<math.h>
int main()
{
int a;
scanf("%d",&a);
double x = 1.0,x1;
do{
x1 = x;
x = (x1 + a / x1)/2;
}while(fabs(x-x1) > 1e-5); //注意循环执行的条件是大于1e-5,而非小于。
printf("%.3f",x);
return 0;
}
7、筛选N以内的素数
解题思路:
(1)素数:只有1和其本身两个因子。
(2)双重循环,第一层遍历2~N的数,第二层遍历1 ~ N-1的因子,如果存在因子,将flag 置 1,否则仍为0.在输出素数时,通过flag的值进行判断。