学C的第七天(继续 深入了解 循环语句,学习二分查找‘折半查找算法’;练习:计算n的阶乘、计算阶乘再相加、在有序数组中查找某个数字、多个字符从两端移动向中间汇聚、模拟用户登录情景)-2

简介: 练习:1.计算n的阶乘(不考虑溢出)

练习:

1.计算n的阶乘(不考虑溢出):

//计算 n的阶乘
#include <stdio.h>
//5!= 1 * 2 * 3 * 4 * 5 
//先用循环生成1-n个数字,再依次相乘
int main()
{
  int n = 0;
  scanf("%d", &n);
  int i = 0;
  int ret = 1; // 相乘后赋值给该函数,因为0乘任何数都为0,所以初始化为1
  for ( i = 1; i <= n; i++) // 利用循环生成1-n个数字
  {
    ret = ret * i; // 依次相乘
  }
  printf("%d\n", ret);
  return 0;
}


be0fb77f2e9c4a11a691d888790771e0.png

2.计算1! + 2! + 3! +...+ 10! :

第一种方法效率比较低,会重复计算之前的计算过的阶乘,但逻辑比较好理解

//计算1! + 2! + 3! +...+ 10! :
#include <stdio.h>
//5!= 1 * 2 * 3 * 4 * 5 
//内循环:循环生成1-n个数字,再依次相乘
//外循环:阶乘相加
int main()
{
  int n = 0;
  int i = 0;
  int ret = 1; // 相乘后赋值给该变量,因为0乘任何数都为0,所以初始化为1
  int sum = 0; // 外循环将阶乘相加赋给该值
  //外循环:阶乘相加
  for ( n = 1; i <= 10; n++) // 加到10!
  {
    ret = 1; // 内循环中相乘后赋值给该变量,每次出了循环要重新刷新该值(重点)
    //内循环:循环生成1-n个数字,再依次相乘
    for (i = 1; i <= n; i++) // 利用循环生成1-n个数字
    {
      ret = ret * i; // 依次相乘
    }
    sum += ret; // 将阶乘相加赋给该值
  }
  printf("%d\n", sum);
  return 0;
} 


image.png

第二种方法:在原本已计算的阶乘上再乘上’下一个数‘,实现‘下一个数’的阶乘)

//第二种方法:
//计算1! + 2! + 3! +...+ 10! :
#include <stdio.h>
//5!= 1 * 2 * 3 * 4 * 5 
int main()
{
  int n = 0;
  int i = 0;
  int ret = 1; // 相乘后赋值给该变量,因为0乘任何数都为0,所以初始化为1
  int sum = 0; // 将阶乘相加赋给该值
  for (n = 1; n <= 10; n++) // 执行到10!
  {
    ret = ret * n; // 直接乘n,
    //在原本已计算的阶乘上再乘上’下一个数‘,实现下一个数的阶乘
    sum += ret; // 将阶乘相加赋给该值
  }
  printf("%d\n", sum);
  return 0;
}


image.png

3.在一个有序数组中查找具体的某个数字n。(讲解二分查找算法‘折半查找算法’):

第一种方法逻辑简单,而且在无序数组中也可以使用,但效率较低,需要一个一个查找)

//在一个有序数组中查找具体的某个数字n。
#include <stdio.h>
int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; // 升序(有序数组)
  //数组下标:  0 1 2 3 4 5 6 7 8 9
  int find = 7; // 在数组中要找的值
  int i = 0; // 数组下标
  //利用for循环在数组中一个一个查找
  for ( i = 0; i < 10; i++ )
  {
    if (arr[i] == find) 
    {
      printf("找到了,该值在数组中对应的下标是:%d\n", i);
      break; // 找到后跳出循环
    }
  }
  if (i == 10) // 10超过数组下标了,说明数组中没有这个值
  {
    printf("数组中没有该值。\n");
  }
  return 0;
}

image.png

第二种方法二分查找算法‘折半查找算法’,在有序数组查找中效率更高,一次查找就能排除一半的值,重点!!)

思路:(重点!!))

改错:“对比中间下标和所找值的下标”,是要对比数组中对应下标的值


4c2c474712254cf7bd3c38a5386588a9.png

代码实现:结合上面原理图理解)

//第二种方法
#include <stdio.h>
int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; // 升序(有序数组)
  //数组下标:  0 1 2 3 4 5 6 7 8 9
  int find = 7; // 在数组中要找的值
  int i = 0; // 数组下标
  int sz = sizeof(arr) / sizeof(arr[0]); // 求元素个数
  // sizeof(arr): 计算数组总大小(单位是字节)
  // sizeof(arr[0]):计算数组中单个元素大小
  // 用 sizeof(arr) / sizeof(arr[0]) ,总大小 除以 单个大小 = 元素个数
  // 1. 求左下标和右下标:
  int left = 0; // 左下标
  int right = sz - 1; // 右下标
  // 因为数组是从0开始得,所以用 元素个数-1 得出 最右边下标
  int flag = 0; // 用来设置未找到情况下的处理
  //循环查找:
  while ( left <= right ) 
  // left <= right: 说明被左右下标包裹中的数组还有值,还有值就继续循环查询
  {
    // 2.确定中间元素下标:
    int mid = (left + right) / 2;
    //进行查找:
    //找到:
    if (arr[mid] == find)
    {
      printf("找到了,该值在数组中对应的下标是:%d\n", mid);
      flag = 1;
      break;
    }
    //未找到:
    //中间值小于要找的值,排除mid和小于mid左边的值      
    else if (arr[mid] < find)
    {
      left = mid + 1; // 调整左下标
    }
    //中间值大于要找的值,排除mid和大于mid右边的值
    else
    {
      right = mid - 1; // 调整右下标
    }
  }
  if (flag == 0)
  {
    printf("没找到\n");
  }
  return 0;
}


image.png

4.编写代码,演示多个字符从两端移动,向中间汇聚:

Sleep(1000)休眠1秒后再执行后面语句,Sleep需要一个windows.h的头文件

system("cls"):system函数可以执行系统命令cls是清理屏幕

//编写代码,演示多个字符从两端移动,向中间汇聚:
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main()
{
  //利用字符数组来存储字符串,后面隐藏一个\0
  char arr1[] = "welcome to school!!!!!";
  char arr2[] = "######################";
  //定义左右下标:
  int left = 0;
  int right = strlen(arr1) - 1;
  // strlen(数组名称):求数组的长度,计算字符数组中\0前有多少个字符
  // 数组长度 - 1 = 最右端的小标
  while (left <= right) 
  // 如果left > right说明数组中左右下标之间已经没有值了
  // 所以有值则一直循环到无值
  {
    arr2[left] = arr1[left]; // 将arr1靠左边上的值 赋值给 arr2最左边的值
    arr2[right] = arr1[right]; // 将arr1靠右边上的值 赋值给 arr2最右边的值
    printf("%s\n", arr2); // 打印重新赋值后的arr2
    Sleep(1000); // 休眠1秒后再执行后面语句
    //Sleep需要一个windows.h的头文件
    system("cls"); // system函数可以执行系统命令,cls是清理屏幕
    left++; // ”倒数最左“
    right--; // “倒数最右”
  }
  printf("%s\n", arr2);
  return 0;
}

image.png

5.编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序):

strcmp库函数:

两个字符串比较相等不能使用==(等于),应该使用strcmp库函数,需添加<string.h>头文件

       strcmp返回0表示2个字符串相等

       strcmp返回>0的数字,表示第一个字符串大于第二个字符串

       strcmp返回<0的数字,表示第一个字符串小于第二个字符串

       字符串比较大小:比较对应位置字符的ASCII值

abcd 和 abq 比较:第一位a=a,第二位b=b,第三位c<q(c的ASCII值小于q的)

       所以 abcd < abq

//5:
#include <stdio.h>
#include <string.h>
int main()
{
  int i = 0;
  //假设密码是:“123456”
  char password[20] = {0};
  int flag = 0;
  for ( i = 0; i < 3; i++) // 循环3次
  {
    printf("请输入密码:>");
    scanf("%s", password);
    // 因为password是数组,数组名本来就是地址,所以不用加取地址符&
    // 判断密码是否正确:
    // 两个字符串比较相等不能使用==(等于),
    // 应该使用strcmp库函数,需添加<string.h>头文件
    // strcmp返回0表示2个字符串相等
    // strcmp返回>0的数字,表示第一个字符串大于第二个字符串
    // strcmp返回<0的数字,表示第一个字符串小于第二个字符串
    // 字符串比较大小:比较对应位置字符的ASCII值
    // abcd 和 abq 比较:第一位a=a,第二位b=b,第三位c<q(c的ASCII值小于q的)
    // 所以 abcd < abq
    if (strcmp(password, "123456") == 0)
    {
      printf("登录成功\n");
      flag = 1;
      break; // 成功则跳出循环
    }
    else 
    {
      printf("密码错误\n");
    }
  }
  if (flag == 0) 
  {
    printf("退出程序\n");
  }
  return 0;
}

image.png

补充内容:变量的左值右值

//变量的左值和右值
#include <stdio.h>
int main()
{
  int a = 10; // 在内存申请名叫a的空间,把10存进去
  a = 20; // 把20放在a的这块空间里,这里使用的是a的空间
  int b = a; // 这里是使用了a中存放的值,把a中的20存放到b的空间(使用的是b的空间)中
  //使用变量空间的变量就是 左值  , 使用变量中存放的值的变量是 右值
  //  简单理解       (空间)                          (空间的内容) 
  return 0;
}

888332b6e66347e5bb578d4983b35b11.png

相关文章
|
11天前
|
机器学习/深度学习 算法 前端开发
Scikit-learn进阶:探索集成学习算法
【4月更文挑战第17天】本文介绍了Scikit-learn中的集成学习算法,包括Bagging(如RandomForest)、Boosting(AdaBoost、GradientBoosting)和Stacking。通过结合多个学习器,集成学习能提高模型性能,减少偏差和方差。文中展示了如何使用Scikit-learn实现这些算法,并提供示例代码,帮助读者理解和应用集成学习提升模型预测准确性。
|
11天前
|
机器学习/深度学习 算法 Python
使用Python实现集成学习算法:Bagging与Boosting
使用Python实现集成学习算法:Bagging与Boosting
20 0
|
18天前
|
算法 测试技术 Serverless
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
|
18天前
|
算法
【算法学习--字符串】(不含KMP算法)
【算法学习--字符串】(不含KMP算法)
|
1月前
|
算法 索引
算法思想总结:二分查找算法
算法思想总结:二分查找算法
|
1月前
|
Rust Dart 算法
55.3k star!开源算法教程,附带动画图解,学习算法不再苦恼!
55.3k star!开源算法教程,附带动画图解,学习算法不再苦恼!
|
1月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
|
1月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Canny边缘检测算法
Opencv(C++)学习系列---Canny边缘检测算法
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真