ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言中阶第四篇:分支与循环语句练习,求阶乘的多种方法(两层for循环求阶乘)、二分查找、字符串汇聚以及模拟用户登录

2022-02-05 19:34:16  阅读:121  来源: 互联网

标签:right int ret C语言 查找 循环 阶乘 left


业精于勤荒于嬉,行成于思毁于随。
今天就来综合的联系一下前面的知识。

第十篇

一、for语句,两种方法计算阶乘

计算阶乘,我们就得明白,阶乘是怎么乘的(思考过程很重要)。我们用一个例子来看一下:

1.1、一层for循环求阶乘

5!=54321,那么我们发现它其实就是12345,我们使用for循环实现一下:

#include<stdio.h>
int main()
{
    int i, ret = 1;
    int n;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {
        ret *= i;
    }
    printf("%d!=%d\n", n, ret);
    return 0;
}

在这里插入图片描述
当然,我们发现,阶乘还有别的特点,比如:
5!= 54!,4!=43!,3!=32!,2!=21,所以我们还可以使用两层for循环实现阶乘,同时,这跟计算阶乘的累和也一样,所以我们先看一看如何实现阶乘的累和:

1.2、实现阶乘累和

阶乘累和,也就是把多个阶乘加起来,那么我们可以使用一个for循环来计算阶乘,再使用一个for循环改变阶乘的对象,也就是下面的代码:

#include<stdio.h>
int main()
{
    int i, j, ret, sum = 0;
    int n;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {
        ret = 1;
        for (j = 1; j <= i; j++)
        {
            ret *= j;
        }//这一个for循环用来计算阶乘
        sum += ret;
    }//这一个for循环用来求和
    printf("%d!=%d\n", n, sum);
    return 0;
}

结果如图:
在这里插入图片描述

1.3、两层for循环求阶乘

那么现在我们再来看看两层for循环实现求阶乘(主要是锻炼思维):

5!= 5 * 4!,4!=4 * 3!,3!=3 * 2!,2!=2 * 1
这个该怎么改代码?
其实式子需要修改成这样:
5!=5 * 4 * 3 * 2 * 1 = 4 * 4!+4!,现在是不是豁然开朗?

现在我们把式子写完全:

5!=4 * 4!+4!
4!=3 * 3!+3!
3!=2 * 2!+2!
2!=1 * 1!+1!

所以n!=(n-1)(n-1)! + … + 44!+33!+22!+1!+1

所以我们发现,求阶乘本身其实本质就是求阶乘的累和(所以也可以递归求解阶乘,笔者递归求阶乘的链接:递归:斐波那契数列、阶乘、求字符串长度、n的k次方的分析):

#include<stdio.h>
int main()
{
    int i, j, ret, sum = 0;
    int n;
    scanf("%d", &n);
    for (i = 1; i <= n - 1; i++)
    {
        ret = 1;
        for (j = 1; j <= i; j++)
        {
            ret *= j;
        }//这一个for循环用来计算阶乘
        sum += i * ret;
    }//这一个for循环用来求和
    printf("%d!=%d\n", n, sum + 1);
    return 0;
}

分析的过程很重要:
在这里插入图片描述

二、if语句,二分查找(在一个有序数组里查找某个具体的数字n)

二分查找,也叫折半查找,当然,使用的前提是数组有序,就是说:

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

我们以在1-10的数字中查找7为例:(只需查找四次
在这里插入图片描述

假设我们查找的数字是7,那么第一步,会首先查找下标(0+9)/2 = 4,判断比5大还是比5小;

而后发现比5大,所以右移,与5 - 9的中间数字(5 + 9) / 2 = 7比较;

这个时候,发现8比7大,所以right下标左移,移到下标7的左边

而后left下标所指的数字比我们要找的所以右移,但因为不能超过right,所以最终left = right,查找结束

注意前提条件:数组必须有序!

现在我们代码实现一下这个过程:

int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    //查找k
    int sz = sizeof(arr) / sizeof(arr[0]);
    int k = 7;
    int left = 0;
    int right = sz - 1;
    while (left <= right) {
        //一次查找:
        int mid = (left + right) / 2;
        if (arr[mid] < k)//小了就left右移
        {
            left = mid + 1;
        }
        else if (arr[mid] > k)//大了就right左移
        {
            right = mid - 1;
        }
        else
        {
            printf("找到了,下标是:%d\n", mid);
            break;
        }
    }
    if (left > right)
        printf("没找着\n");
    return 0;
}

重在分析

三、模拟字符串向中间汇聚

比如:
Hello World! 应该这样出现:
H########!
He######d!
Hel#####ld!

Hello World!

这个其实比较简单,我们定义两个字符数组,然后覆盖赋值就可以,直接看代码吧:

#include<stdio.h>
#include<string.h>
#include<windows.h>
int main()
{
	char str1[] = { "Hello World!" };
	char str2[] = { "############" };

	int left = 0;
	int right = strlen(str1) - 1;
	while (left <= right)
	{
		str2[left] = str1[left];
		str2[right] = str1[right];
		printf("%s\n", str2);
		Sleep(500);//每次延迟500毫秒
		left++;
		right--;
	}
	return 0;
}

结果如图:
在这里插入图片描述
当然,也可以使用system(“cls”)来实现每次清屏,让结果看起来更有汇聚的感觉,使用延迟就是为了让程序体现出慢慢汇聚的感觉,感兴趣的小伙伴可以用代码试一试。

四、模拟用户登录

我们编写代码模拟用户登录的情景,并且只允许登录三次(就是只能三次输入密码,密码正确就登录成功,如果三次均失败,就退出程序)

这里我们使用一个库函数:strcmp:
在这里插入图片描述
在这里插入图片描述
这里只需要注意它的返回值:
在这里插入图片描述
我们假设密码是确定的(也可以先让用户输入),那么我们来看一看代码吧:

#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	char password[20] = { 0 };
	//假设密码是“abcdef”
	char pw[] = { "abcdef" };
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:\n");
		scanf("%s", password);
		if (strcmp(password, pw) == 0)
		{
			printf("密码正确,登陆成功!\n");
			break;
		}
		else
			printf("密码错误,请重新输入:\n");
	}
	if (i == 3)
		printf("三次密码均输入错误,退出程序\n");
	return 0;
}

运行结果如图:
在这里插入图片描述

标签:right,int,ret,C语言,查找,循环,阶乘,left
来源: https://blog.csdn.net/awaitxm/article/details/122787191

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有