求阶乘:
用户输入一个正整数n,编写一个程序求出n的阶乘。
分析:求一个正整数的阶乘,即求1234….*(n-1)*n。我们只需生成从1到n的所有数字并相乘最后存储值即可。
代码如下:
#include <stdio.h>
int main()
{
int n=0;
int res=1; //注意这里不能初始化成0,因为0乘任何数都是0
printf("输入数字:>");
scanf("%d",&n);
for(int i=1;i<=n;i++) //通过for循环生成1到n的所有数字
{
res*=i;
}
printf("%d",res);
return 0;
}
求阶乘和:
用户输入一个数字,编写程序算出这个数字的阶乘和。比如用户输入5,则要求程序算出 1! + 2! + 3! + 4! + 5!
分析:首先要求阶乘,阶乘程序已经编写出,只需在求阶乘的代码上进行修改即可。
首先最容易想的应该就是用两个嵌套的for循环:
#include <stdio.h>
int main()
{
int n=0;
int res=0; //注意这里不能初始化成0,因为0乘任何数都是0
printf("输入数字:>");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int sum=1; //这里的sum在嵌套的for结束时要重新初始化,不然sum就是上一个数字的阶乘结果,会越来越大
for(int j=1;j<=i;j++)
{
sum*=j;
}
res+=sum;
}
printf("%d\n",res);
return 0;
}
这个算法很容易理解,但仔细分析一下,以求5的阶乘和为例:
1! = 1
2! = 1! * 2
3! = 2! * 3
4! = 3! * 4
5! = 4! * 5
….
那么n!=(n-1)! * n
根据两个for循环的算法可知:内部的for循环,都重复着一个相同的动作,那我们就可以在外部的for循环来求当前数字的阶乘并在当前循环快结束的时候,用变量储存当前数字的阶乘的结果:
#include <stdio.h>
int main()
{
int n=0;
int sum=0;
int res=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
res*=i;
sum+=res; //用sum存储当前数字的阶乘结果
}
printf("%d",sum);
return 0;
}
该算法相较于两个for嵌套的for循环而言更简便。
二分查找
二分查找是一种查找算法,一次性可以去除一半的数据,效率很高。但效率高的同时对数据本身也有一个很苛刻的要求,就是需要数据有序排列,升序和降序都可以。这里为了方便我们用升序。
分析:对于一个升序排列的数组arr,我们需要在里面查找一个我们需要的数据,如果查找到了,提示我们并且返回它的下标;如果没查找到提示我们找不到。我们定义两个变量,分别是left和right,定义我们需要查找的数据为k,再定义一个标示我们找到数据的变量flag并初始化为0。从这里开始,体现二分查找的思想,我们定义一个变量mid=(left + right) / 2,取到数组中间的数据,而又因为我们的数组升序排列,如果k>arr[mid],说明我们中间的数据在我们需要查找的数据的左边,此时我们将left赋值为mid+1;如果k<arr[mid],说明我们中间的数据在我们需要查找的数据的右边,此时我们将right赋值为mid-1。重复如此,可发现上述过程其实是一个循环,而循环的结束条件是left>right。如果我们可以查找的数据,则此时这个数据的下标就是mid,返回并将flag置为1即可。如果找不到,则flag还是0,提示我们找不到即可。
算法如下图:
#include <stdio.h>
int main()
{
int arr[] = { 1,2,4,6,7,8,9,10,99,100 };
int sz = sizeof arr / sizeof arr[0];
int left = 0;
int right = sz - 1;
int k = 0;
int flag = 0;
scanf("%d", &k);
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k) //中间的值小于要查找的值
{
left = mid + 1; //将left变成mid+1,缩小查找范围,体现了二分查找的思想!
}
else if (arr[mid] > k)
{
right = mid - 1; //同上面的leflt
}
else
{
flag = 1;
printf("找到了,下标为:%d", mid);
break;
}
}
if (flag == 0)
{
printf("找不到");
}
return 0;
}
一串字符从两边向中间靠拢的演示
给定一串字符,编写程序演示其从两边向中间靠拢的过程。
分析:该题和二分查找有相似之处。也是一个循环,循环结束的条件也是left>right,不做过多分析了:
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
char arr1[] = "Hello World!";
char arr2[] = "************";
int left = 0;
int right = sizeof arr1 / sizeof arr1[0] - 1;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000); //用Sleep函数停顿一秒输出,为了好看
left++;
right--;
}
return 0;
}