c_lesson7
1.Lesson 6遗留问题
1.赋值所造成的的陷阱
2.输出1-100之间3的倍数
3.三个数排序
1.1 赋值所造成的的陷阱
思路:由于i=5是赋值语句,所以造成了死循环;想修改要改成i==5
#if 1
#include <stdio.h>
#include <windows.h>
int main()
{
int i = 0;
for(;i<10;i++)
{
if(i = 5)//死循环
//if(5 == i)//正确做法
{
printf("11111111111111111");
}
}
system("pause");
return 0;
}
#endif
1.2 输出1-100之间3的倍数
思路:
1.循环输出1-100之间的数;
2.3的倍数,则i%3==0
#if 1
#include <stdio.h>
#include <windows.h>
int main()
{
int i = 0;
for(i=2;i<100;i++)
{
if(i%3 == 0)
{
printf("%d ",i);
}
}
printf("\n");
system("pause");
return 0;
}
#endif
函数实现
#if 0
#include <stdio.h>
#include <windows.h>
int IsThree(int x)
{
return x%3==0;
}
int main()
{
int i = 0;
for(i=2;i<100;i++)
{
if(IsThree(i))
{
printf("%d ",i);
}
}
printf("\n");
system("pause");
return 0;
}
#endif
1.3 三个数排序
思路:一一列举
1.a>b && b>c —>a,b,c
a>b && c>b && a>c —>a,c,b
a>b && c>b && c>a —>c,a,b
2.a<b && b>c && a>c —>b,a,c
a<b && b>c && a<c —>b,c,a
a<b && b<c —>c,b,a
#if 1
#include <stdio.h>
#include <windows.h>
void ThreeSort(int _a,int _b, int _c)
{
if(_a>_b){
if(_b>_c){
printf("%d %d %d\n",_a,_b,_c);
}else{
if(_a>_c){
printf("%d %d %d\n",_a,_c,_b);
}else{
printf("%d %d %d\n",_c,_a,_b);
}
}
}else{
if(_b>_c){
if(_a>_c){
printf("%d %d %d\n",_b,_a,_c);
}else{
printf("%d %d %d\n",_b,_c,_a);
}
}else{
printf("%d %d %d\n",_c,_b,_a);
}
}
}
int main()
{
int a = 0;
int b = 0;
int c = 0;
printf("输入三个整数:\n");
scanf("%d %d %d",&a,&b,&c);
ThreeSort(a,b,c);
printf("\n");
system("pause");
return 0;
}
#endif
2.Lesson7遗留问题
1.打印1000-2000之间的闰年
2.打印100-200之间的素数
3.求两个数的最大公约数
2.1 打印1000-2000之间的闰年
思路:
1.闰年:(_year%4 == 0)&&(_year%100 != 0)四年一润,百年不润
(_year%400 == 0)四百年再润
2.1000-2000年之间需要用循环实现
3.如果是闰年,返回1,并且打印这个年份;不是闰年,返回0,不执行。
#if 1
#include <stdio.h>
#include <windows.h>
int IsRun(int _year)
{
return ((_year%4 == 0)&&(_year%100 != 0) || (_year%400 == 0)) ? 1 : 0;
}
int main()
{
/*int year = 0;
printf("请输入年份:\n");
scanf("%d",&year);
int ret = IsRun(year);
if(ret == 1){
printf("是闰年\n");
}else{
printf("不是闰年\n");
}*/
int year = 1000;
for(;year<=2000;year++)
{
if((IsRun(year)) == 1){
printf("%d ",year);
}
}
printf("\n");
system("pause");
return 0;
}
#endif
2.2 打印100-200之间的素数
思路:素数就是除自己和1之外,没有其他的因数。
code1:1.遍历除1和它本身的其他因子。[2,_num-1]
2.如果这个数能整除i(除1和它本身的数),则不是素数,返回0;否则是素数,返回1。
code2:因为一个数,至少是某个数的2倍,比如1-10,则6-10就是1-5的2倍,所以后面的就不用再进行遍历。
code3:1.因为一个数必然由一个大数*一个小数构成,最大到两个数相等
_num = m*n(m大,n小)
_num = m*n(m,n) (m和n相等)
比如:100
100==20*5 100%20 == 0;100%5==0
100==10*10 100%10 == 0;100%10==0
所以我只需要遍历至sqrt(_num)。
2.如果能整除i,则则不是素数,返回0;否则是素数,返回1。
#if 1
#include <stdio.h>
#include <windows.h>
#include <math.h>
//code 1
//int IsPrime(int _num)
//{
// int i = 0;
// //遍历除1和它本身的其他因子。[2,_num-1]
// for(i=2; i<_num;i++){
// //如果这个数能除进(除1和它本身的数),则不是素数
// if(_num%i == 0){
// //不是素数
// return 0;
// }
// }
// //是素数
// return 1;
//}
//code 2
//int IsPrime(int _num)
//{
// int i = 0;
// //因为一个数,至少是某个数的2倍,比如1-10,则6-10就是1-5的2倍,所以后面的就不用再进行遍历。
// for(i=2; i<=_num/2;i++){
// if(_num%i == 0){
// break;
// }
// }
// //1.循环条件不成立;2.break跳出
// if(i<=_num/2){
// //不是素数
// return 0;
// }
// //是素数
// return 1;
//}
//code 3
int IsPrime(int _num)
{
int i = 0;
int top = (int)sqrt((float)_num);
//因为一个数必然由一个大数*一个小数构成,最大到两个数相等
//_num = m*n(m大,n小)
//_num = m*n(m,n) (m和n相等)
//比如:100
//100==20*5 100%20 == 0;100%5==0
//100==10*10 100%10 == 0;100%10==0
//所以我只需要遍历至sqrt(_num)。
for(i=2; i<=top;i++){
if(_num%i == 0){
break;
}
}
//1.循环条件不成立;2.break跳出
if(i<=top){
//不是素数
return 0;
}
//是素数
return 1;
}
int main()
{
/*int num = 0;
printf("请输入一个数:\n");
scanf("%d",&num);
int ret = IsPrime(num);
if(ret == 1){
printf("是素数\n");
}else{
printf("不是素数\n");
}*/
int num = 100;
for(;num<=200;num++)
{
if((IsPrime(num)) == 1){
printf("%d ",num);
}
}
printf("\n");
system("pause");
return 0;
}
#endif
2.3 求两个数的最大公约数
思路:两个数的最大公约数:两个数能被整除的最大因数,比如:100 40的最大公因数就是20。
两个数都能被某个数整除,则这个数就是因子,而最大的因子,就是最大公约数
code1:穷举法
1.两个数中必然有一个大数m,有一个小数n,最大因数一定小于等于小数n。
注:先求解出哪个数小。
2.要想求最大公因数,遍历i【2,n】,使用循环
3.如果m%i==0 && n%i==0,则这个数就是两个数的因数。最大的是最大公约数。
为了更快的求最大公约数,循环使用倒序【n,2】的形式来,也就是所谓的i--;
遇到的第一个因数就是最大公约数。
4.如果是最大公约数,则返回i值;如果遍历没找到,最大公因数就是1,则返回1.
code2:辗转相减法
例如 :两个自然数35和14,用大数减去小数, (35,14)-> (21,14)-> (7,14),
此时,7小于14,要做一次交换,把14作为被减数,即 (14,7)-> (7,7),再做一次相减,结果为0,
这样也就求出了最大公约数7。
1.两个数中必然有一个大数m,一个小数n。假定最大公约数为T
大数:(T+T+T...T+T+T) 小数:(T+T...T+T)
2.大数-小数:(T+T+T...T+T+T)-(T+T...T+T) = (T...T+T)
程序思路:1.判断哪个数大。
2.如果_x>_y; ---> _x = _x-_y
如果_x<_y; ---> _y = _y-_x
如果_x=_y; ---> 这个数就是最大公约数
3.因为两个数要多次进行上面的操作,然后找到最大公约数(while(1))
code3:辗转相除法
两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数
例如:假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。
所以就得出了 1997 和 615 的最大公约数 1。
程序思路:1.求出最小数。
2.如果_x>_y,则_x = _x%_y;将所求余数,赋值给大的数,因为每次把大数就排除了。
如果_x<_y,则_y = _y%_x;
如果_x=_y,则余数就为0,此时这个就是最大公约数。
3.因为两个数要多次进行上面的操作,然后找到最大公约数
4.循环条件:对于除数和余数这一操作符,除数一定不能为0,因此循环条件为:_x*_y != 0
如果有一个数等于0,则返回另一个不为0的数。
#if 1
#include <stdio.h>
#include <windows.h>
//code1:穷举法
//int GreatestCommonDivisor(int _x,int _y)
//{
// //计算出最小值是哪一个
// int top = (_x>_y)?_y:_x;
// //赋予循环的初值为最小值
// int i = top;
// //倒序进行循环遍历
// for(; i>=2;i--){
// //第一个遇到的,如果两个数都能被i整除,则这个数就是最大公因数
// if((_x%i == 0) && (_y%i == 0)){
// //返回最大公因数
// return i;
// }
// }
// //没有找到最大公因数,最大公因数就是1
// return 1;
//}
//code2:辗转相减法特色是做一系列减法,从而求得最大公约数。
//int GreatestCommonDivisor(int _x,int _y)
//{
// while(1){
// if(_x>_y){
// _x = _x-_y;
// }else if(_x<_y){
// _y = _y-_x;
// }else{
// break;
// }
// }
// //找到最大公约数后,break退出循环,返回最大公约数。
// return _x;
//}
//code3:辗转相除法:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数
int GreatestCommonDivisor(int _x,int _y)
{
while(_x*_y != 0){
if(_x>_y){
_x = _x%_y;
}else if(_x<_y){
_y = _y%_x;
}else{
break;
}
}
//1.找到最大公约数后,break退出循环,返回最大公约数。
//2.循环条件不成立
return _x == 0?_y:_x;
}
int main()
{
int x = 0;
int y = 0;
printf("请输入两个数:");
scanf("%d%d",&x,&y);
int ret = GreatestCommonDivisor(x,y);
printf("%d \n",ret);
system("pause");
return 0;
}
#endif