文章目录
- 1. 计算 n 的阶乘
- 2. 计算 1!+2!+3!+……+10!
- 3. 使用二分查找法查找某数
- 二分查找算法介绍
- 代码实现
- 4. 演示字符移动
- 5. 模拟用户登录场景
1. 计算 n 的阶乘
阶乘
- 某个数从 1 开始一直乘到这个数本身为止;
- 例如:3 的阶乘就是 1 * 2 * 3 = 6;
- n 的阶乘就是 1 * 2 * 3 … * n。
解题思路
- 如果想要阶乘到 n 的话,就要产生 1-n 的数字,此时就需要用到循环。
- 通过循环产生 1-n 的数字,然后把这些数字累积乘到一个数上。
代码实现
#include <stdio.h>
int main()
{
int n, i;
int ret = 1;//产生的1-n的数字要累乘到ret上存起来,所以ret必须初始化为1
scanf("%d", &n);
for (i = 1; i <= n; i++)//产生 1-n 的数字
{
ret *= i;//将不断产生的 1-n 的数字累乘到 ret 上
}
printf("%d\n", ret);
return 0;
}
2. 计算 1!+2!+3!+……+10!
解题思路
- 和上一题一样分别计算从 1-10 的每个数的阶乘,并把这些数全部累加到一个变量上去。
代码实现
#include <stdio.h>
int main()
{
int sum = 0,ret = 1;
int i, n;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
ret *= i;//产生从 1-n 的阶乘并且存到 ret 中
sum += ret;//将每次产生的阶乘的结果累加到 sum 中去
}
printf("%d\n", sum);
return 0;
}
3. 使用二分查找法查找某数
题目内容
- 在一个有序数组中查找具体的某个数字 n。
二分查找算法介绍
二分查找
- 每次将待查记录所在区间缩小一半;
- 只对已经排序的数据有效。
查找过程
- 当前数组内的数据元素是按照升序排序的。
- 设置一个查找区间初始值,low 指向第一个元素,high 指向最后一个元素。
- 当 low <= high 时,循环执行以下操作:
- 设一个 mid 为 low 和 high 的中间值:mid = (low + high) / 2,当前这个数组的 mid 是下标 6 的元素 56。
- 直接将要找的这个关键字的值 21 和 和中间位置的这个值比较一下,发现 21 < 56,说明要找的值一定在 mid 的左半边区域。要将查找范围更新到 mid 左边。
- 则将新的 high 更新为:key < mid 则:high = mid - 1,因为中间位置56比较过了,不是这家伙。
- 继续拿 mid 的值和 21 比较,发现 19 < 21,说明待查找的值在 mid 的右边,将 low 更新,key > mid 则: low = mid +1。
- 然后再取找中间位置,low是 4 high 是 5,mid 的值就是4。
- 拿 key 的值 21 和 mid 的值比较,发现 mid == key 则:return mid。
如果要找的值不在数组中
- 查找到最后 low 会大于 high 上下限交换了,此时说明数组中没有俺们要找的数。
- 折半查找结束条件:high < low。
- 因为这样就说明 high 和 low 之间已经没有元素可以被查找了。
二分查找特点
- 在数据越多的时候效率越高,假设要 40 亿的数据中查找,第一次就能去掉20亿的数据。
- 待查找的数据必须是有序的。
代码实现
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组中有多少个元素
int low = 0,high = sz - 1;//high指向的是最后一个元素的下标,所以要 sz -1
int n;
printf("请输入要查找的数:");
scanf("%d", &n);
while (low <= high)//这个循环条件说明两者之间还有元素未被查找
{
int mid = (low + high) / 2;//这一步必须要写进循环里,不然 mid 无法更新
if (arr[mid] > n)//如果中间值大于要查找的值,则去 mid 的左半区域去找
{
high = mid-1;
}
else if (arr[mid] < n)//如果中间值小于要查找的值,则去 mid 的右半区域寻找
{
low = mid + 1;
}
else
{
printf("找到了,下标是%d\n", mid);
break;//已经找到了,再继续找就没意义了
}
}
if (low > high)//中间已经没有元素可以被查找了
{
printf("找不到了\n");
}
return 0;
}
4. 演示字符移动
题目内容
- 编写代码,演示多个字符从两端移动,向中间汇聚。
题目分析
- 假设最终要打印出 hello word!,要演示出的效果就是下面这样;
***********
h*********!
he*******d!
hel*****rd!
hell***ord!
hello*word!
hello word!
解题思路
- 创建两个数组,arr1 用来存 hello word!,arr2 用来存放 ***********。
- 找出两个字符串数组最右端及最左端字符的数组下标。
- 控制左右两端的下标,将 arr1 左右两端的字符从外向里,依次赋值到 arr2 对应的位置上去。
代码实现
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "hello word!";
char arr2[] = "***********";
int left = 0;
int right = strlen(arr1) - 1;//要拿到的是字符串数组的最后一个元素的下标
printf("%s\n", arr2);
while(left<=right)//让 arr1 数组中的左右两端的元素向中间移动,然后依次赋给arr2
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
left++; right--;
printf("%s\n", arr2);
}
return 0;
}
5. 模拟用户登录场景
题目内容
- 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则
提示登录成功,如果三次均输入错误,则退出程序。
代码实现
#include <stdio.h>
#include <string.h>
int main()
{
int i;
char arr1[] = "5201314";
char password[20];
for (i = 0; i < 3; i++)
{
printf("请输入密码:");
scanf("%s", password);//数组名已经是地址了,此处不需要 &password 了
//使用 strcmp 来比较两个字符串是否相等,引用头文件 string.h
//如果两个字符串相等,则 strcmp 的返回值为 0(假)
if (!strcmp(password, arr1))//如果相等则返回的是 0 (假),用 ! 把假变成真
{
printf("登录成功\n");
break;
}
else
{
printf("密码错误,请重试\n");
}
}
if (3 == i)
{
printf("你已输错3次,已退出程序!\n");
}
return 0;
}