[日常练习] 1. 基于素数及闰年判断、打印乘法口诀表的C语言实现


在日常学习中,我们能很快的分析得到一个数是否是素数,了解它的判定法则,但是要是给你100个数,你需要花费多少时间才能判断其中的素数呢?又能保证多少正确率呢?好吧,即便你是数学巧算能手、珠心算大神,100的总量对于你来讲是九牛一毛!!!但是我给你10000+个(我就是刻意为难你胖虎~),您慢慢算吧!

乘法口诀表算是我们学习数学的一个“大障碍”,小时候背不出来、背错被揍的经历大多数人都经历过,但是能用自己所学的编程知识打印得到一份完整的9*9的乘法表吗?那要是n*n呢?

闰年判断也是一个编程学习的初步难点,重在它的逻辑上面,有很大一部分同学都会漏掉某些“特殊的年”,像是1600,2000等,为什么会出现这个情况呢?我们能否在大量年份数据面前可以很快、准的判断出里面那些是闰年,那些不是闰年,并且统计它的个数呢?


练习题目:

1. 打印100~200 之间的素数
2. 输出乘法口诀表
3. 判断1000年---2000年之间的闰年

题目分析及代码:

1. 在C语言中素数的判别法很多,最基本的是一个数i,如果它能够整除前面的i-1个数,那么它不是素数,反之则是。也有将判断条件从i-1缩减到\sqrt i,来减小判断循环的次数。在此我们选择后者进行判断。当然,也有很多判断方式方法,在以后的学习中一定要学习各个方法的长处,注意总结!

#include<stdio.h>
#include<math.h>

int main()
{
	int i = 0;
	int count = 0;

	for(i = 101; i<200; i+=2)            //偶数在此不需要进行判断
	{
		int j = 0;
		for(j=2; j<=sqrt(i); j++)    //算法优化
		{
			if(i%j == 0)
			{
				break;
			}
		}

		if(j>sqrt(i))
		{
			count++;             //计算素数个数
			printf("%d ", i);    //依次打印各个素数
		}
	}

	printf("\ncount = %d\n", count);     //打印素数总数
	return 0;
}

上面就有我们的C语言程序代码及运行结果,是不是正确呢?那当然是正确的了...

在此我们需要注意到的是:

1. 偶数不需要进行素数判断,故i可以累次递加2,这样就会减少很大一部分无用的循环。但是,i的初值也要相应的修改!

2. 也是在判断的条件上,选用\sqrt i进行处理,相较于最基本的以i-1进行判断的方法,也是很大进步。

3. 计算所求得的素数的个数,count可以直接求出,但是也是要注意它在循环体中的位置。

回味:

素数可谓是很重要、特殊的数字了,在数学上有很大的作用,有著名的“哥德巴赫猜想”,素数在此扮演了重要的角色。在C语言中的素数判断程序中,首先需要很熟练的将其写出来。之后需要再学习2--4种其它优秀的判别方法,优化的算法思想是素数判别问题的重点。这就需要自己去挖掘了!!!


2. 打印乘法口诀表,数据依次递加,格式规整,这无疑是要使用到循环的。然而循环的使用我们需要注意到的是:循环变量的赋初值、限值条件这两个重要因素。在9*9表中,它的第一特征是个正下三角形,要是从列的角度进行观看的话,我们会发现,列数并不能很显著的展示它的特征。来反观行数,第一行1个,第二行2个,第三行3个...第i行i个,那么一行的算术个数就与被乘数相同,那么这样的一个累加过程就可以用循环实现!

#include<stdio.h>
int main()
{		
	int i = 0;
	int j = 0;
	for(i=0; i<=9; i++)          //寻找乘数与被乘数的关系
	{
		for(j=1; j<=i; j++)      //9*9乘法表,每一行的个数等于i,而j每次都要从1开始,所以在此j的限制条件可以得到j<=i
		{
			printf("%d*%d=%2d ", i, j, i*j);   //打印每一行,注意 %2d 的使用让打印格式更加整齐
		}
		printf("\n");            //打印完毕一行时,要进行换行
	}
	return 0;
}

上面就是我们的C语言实现源码和结果,这显然是正确的!

在此我们需要注意到的是:

1. 需要将问题转化为循环的问题,需要进行一定的转化,j的初值以及定解问题,这就需要程序的思维!

2. 在初次打印的时候,我们会发现每个数字并不能对齐,这就是二位数字所占的位数的问题,需要进行调整。''%d*%d=%2d'',这是一个很良好的调整方案,但是要是产生三位数了呢?要是需要进行“智能的对齐”呢?

回味:

9*9乘法表代表着“童年的记忆”,在C语言实现中,是循环很好的体现。在此我们编了9*9的,可以顺利解决,也能解决它的排版问题。但是再让我们回到最初的问题,我们是否可以从列中寻找到其中的关系?能否进行“智能的对齐”呢?打印9*9乘法表是最基础的程序了,一定要牢记!


3.闰年4年一次,一次一年多一天。要是谁的生日正正好好的就在那多的一天上面,也就是罕见的2月29日,4年一次的生日也是可以好好的操办一下了。判断闰年的条件我们可以得到被4整除,被400整除,循环结构这要怎么实现呢?在判断条件如此多的情况下,会不会缺漏条件呢?拭目以待!

#include<stdio.h>
int main()
{
	int year = 0;
	int count = 0;
	for(year=1000; year<=2000; year++)     
	{
		if(((year%4==0)&&(year%100!=0))||(year%400==0))    //判断条件
		{
			printf("%d ",year);                            
			count++;                                       //计数1
		}
	}
	if(year%400 == 0)                                      //被400整除也是闰年
	{
		count++;                                           //
		printf("%d ",year);
		
	}
	printf("\n1000--2000年闰年总数:%d 年\n",count);
	return 0;
}

上面就是我们的C语言实现源码和结果,这我也无法保证正确性了...大家可以自行验证一波!

在此我们需要注意到的是:

1. 我们在判断条件的时候,用到了“逻辑与”、“逻辑或”,这里判断的时候,电脑会偷懒懒的!!!在“逻辑或”前件为真时,整体就已经为真了,后件就不需要进行判断了,电脑也很聪明,自动跳过这个判断。这当然不是我们所需要的!!! 在if语句中,大家可以将“逻辑或”中的顺序进行交换,看看结果是否有变化。

2. 发现程序在中删减某些项的代码(删掉if判断语句)不影响最后的结果,这个闰年的判断的程序是过于繁琐还是我的操作有问题呢?

3. 闰年的判断,顺序还有什么要注意的呢???

回味:

在闰年判断里面其实逻辑并不复杂,但是总是会出现某些年份丢掉了,此时,我们要看看那些逻辑被丢掉了呢?还是有些问题被我们忽略掉了?这就要考我们问题的细心程度、问题的掌握程度了,得好好积累了!

日常:

以后会进行一些习题的处理,学习中的特立独行的想法也会再次提出。此外对于Matlab以及LaTeX的学学习可能也会 放到上面,写写自己的心得,希望能够在自己的学习之路上。它能记录下我的点滴进步!

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/83041823