最近又开始重新过了一边C语言,到了分支和循环语句的部分,做了几个练习题来分享一下,话不多说,进入正题!
第一道题目:求N!的值
这里呢,因为是要求N的阶乘,计算公式为1*2*3*...*n; 我们应该敏感的是,这里出现了1,2,3,这样的连续数字,我们最先想到的肯定是循环语句;
用for循环来做:
//求N的阶乘
int main()
{
int a = 0;
int i = 0;
int sum = 1;
scanf("%d",&a); //输入我们要求的n
for (i = 1; i <= a; i++)
{
sum = sum * i;
}
printf("%d\n",sum);
return 0;
}
这里选择1为i的初始值,是因为,我们的计算是从1,开始的,而判断条件为i<=a;是因为,我们算到最后是要乘以a的;所以说以i<=a;为判断条件;
用while循环来做:
int main()
{
int a = 0;
int i = 1;
int sum = 1;
scanf("%d",&a);
while (i <= a)
{
sum = sum * i;
i++;
}
printf("%d\n",sum);
return 0;
}
第二道题目:求1-10每个数的阶乘之和
这道题目我们可以联系上一道题目来做,因为上一道题目,求的是n的阶乘,把n依次换成1,2,3,4等数字,再把每个数的阶乘加起来就算出来了;这个时候我们就用到了,嵌套的循环语句;
常规思想:
//求1-10各个数阶乘的和
int main()
{
int i = 0;
int a = 0;
int sum = 1;
int sum1 = 0;
for (i = 1; i <= 10; i++)
{
for (a = 1; a <= i; a++)
{
sum = sum * a;
}
sum1 = sum + sum1;
sum = 1;
}
printf("%d\n",sum1);
}
可以看到,我们内部的for循环,是和上到题目的for循环是一样的,所以说,我们内部的for循环是计算每个数的阶乘,而外部的for循环的作用,就是将1,2,3,4,。。。,10,这是个数分别输入进去的;最后,再把每次的计算结果相加就得到我们需要的结果啦;
仔细探索:
我们可以仔细对比一下,我们计算
1的阶乘为1
2的阶乘为1*2
3的阶乘为1*2*3
其实,不难发现,每次计算的结果都是在之前的一次的结果之上在乘以i;我们就可以做个更简单的过程出来;
//求1-10各个数阶乘的和
int main()
{
int i = 0;
int a = 0;
int sum = 1;
int sum1 = 0;
for (i = 1; i <= 10; i++)
{
sum = sum * i;
sum1 += sum;
}
printf("%d\n",sum1);
}
第三道题目:在一个有序数组中查找具体的某个数字N
常规思路:
我最先想到的就是可以把整个数组遍历一遍,逐个对比在输出结果
//求有序数组的中的某个数n
int main()
{
int i = 0;
int a = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10,0 };
int len = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < len; i++)
{
if (arr[i] == 8)
{
a = arr[i];
break;
}
}
printf("%d\n",a);
}
思路是先根据sizeof();函数计算出数组的长度,在使用for循环以数组长度为判断条件,将数组元素逐个对比,并输出结果;
反思,这样的确可以输出正确的结果,但是,我们写程序要考虑,程序的时间复杂度,我们这样遍历一遍,数组元素少的话还不明显,如果,数组的元素很多呢,程序就会变得很慢;
新学的思路:
在学习的过程,老师提供了一个二分查找也叫拆分查找
代码如下:
int main()
{
int arr[] = { 0,1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int k = 8;
int len = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = len-1;
len = (left + right)/ 2;
while (left <= right)
{
if (arr[len] < k)
{
left = len+1;
len = (left + right) / 2;
}
else if (arr[len] > k)
{
right = len - 1;
len = (right + left) / 2;
}
else
{
printf("找到了值为%d,下标为:%d\n", arr[len],len);
break;
}
}
if (left > right)
{
printf("实在找不到,求放过!!");
}
return 0;
}
这里的思路为,我们抓住一个关键点,这个数组是一个有序数组,所以我们可以进行二分查找,根据求出的数组长度,确定数组的中间数字,并与我们要查的数字k进行比较;
如果,比k小,那么我们要找的数字k还在中间数字的右边,所以,以中间数字的下标+1,作为我们查找范围的第一个下标,查找范围的最后一个数字还为数组最后一个;
如果,比k大,那么我们要找的数字k还在中间数字的左边,所以,以中间数字的下标-1,作为我们查找范围的最后个-下标,查找范围的第一个数字还为数组的一个元素;
一次步骤循环就行,在判断条件的外面再加上一个while循环,判断条件为left<=right;的时候循环结束;
如果,我么定义的left为查找范围的第一个数字,right为查找范围的最后一个数字,最后循环到left>right的时候,说明已经不是我们想要的范围了;