C语言暑假学习刷题——Day4

目录

选择题

考点一:for循环的理解

考点二:while 循环和循环嵌套的理解

考点三:break在switch语句中的应用

考点四:升序插入排序算法的应用

考点五:循环嵌套的理解

编程题

【leetcode 题号:645. 错误的集合】【难度:简单】

【牛客网题号: OR141 密码检查】【难度:简单】


 

选择题

考点一:for循环的理解

1、 设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )

A:n=0; while(ch=getchar() != '\n') n++;

B:n=0; while(getchar() != '\n') n++;

C:for(n=0; getchar() != '\n'; n++);

D: n=0; for(ch=getchar(); ch != '\n'; n++);

正确答案:D

对于 for 循环,其中第一项初始化表达式只执行一次,因此 ch 只从输入流中取一个字符,之后就再不会取字符,因此会死循环

对于getchar库函数

每次只会从从键盘缓冲区读取一个字符,且遇到\n结束读取

对于for循环

 第一个参数为循环的初始化【只执行一次】

 第二个参数为循环的判断条件【每次进行条件判断,决定是否进入下次循环】

 第三个参数为每次循环都执行的语句

考点二:while 循环和循环嵌套的理解

2、 运行以下程序后,如果从键盘上输入65 14<回车>,则输出结果( )

int main()
{
    int m, n;
    printf("Enter m,n;");
    scanf("%d%d", &m,&n);
    while (m!=n) //1
    {
        while(m>n) m=m-n; //2
        while(n>m) n=n-m; //3
    }
    printf("m=%d\n",m);
    return 0;
}

A: 3 B: 2 C: 1 D: 0

正确答案:C

考查 while 循环和循环嵌套的理解,初值 m=65,n=14 ;循环 1 判断 m!=n 为真,来到循环 2 判断 m>n 为真,执行m=m-n;直到 m=9,n=14 ;循环 2 结束来到循环 3 判断 n>m 为真,执行 n=n-m; 直到 m=9,n=5 ;循环 3 结束回到循环 1 ,如此往复直到m==n 时,循环结束

考点三:break在switch语句中的应用

 若运行以下程序时,从键盘输入 ADescriptor<回车> ,则下面程序的运行结果是( )

#include <stdio.h>
int main()
{
	char c;
	
	int v0=0,v1=0,v2=0;
	
	do
	{
		switch(c=getchar())
		{
		case'a':
		case'A':
		case'e':
		case'E':
		case'i':
		case'I':
		case'o':
		case'O':
		case'u':
		case'U':
			v1 += 1;
		default:
			v0+= 1;v2+=1;
		}
	}while(c!='\n');
	printf("v0=%d,v1=%d,v2=%d\n",v0,v1,v2);
	return 0;
}

A: v0=7,v1=4,v2=7

B: v0=8,v1=4,V2=8

C: v0=11,v1=4,v2=11

D: v0=12,v1=4,v2=12

正确答案:D

代码 switch 语句中没有 break ,则每次找到入口进入后,顺序执行到代码块结束为止。例如当 c 为 'A' 时,从 case 'A' 进入,先后执行v1+=1;v0+=1;v2+=1; ,而当 c 为 'p' 时,从 default 进入,先后执行 v0+=1;v2+=1; ,容易看出最终 v0 和 v2 是相等的

考点四:升序插入排序算法的应用

4、 以下程序段的功能是( )

int a[] = {4, 0, 2, 3, 1}, i, j, t;
for(i = 1;i < 5;i++)
{
	t = a[i];
	j = i - 1;
	while(j >= 0 && t < a[j])
	{
		a[j + 1] = a[j];
		--j;
	} 
	a[j + 1] = t;	
}

A: 对数组a进行插入排序(降序) B: 对数组a进行插入排序(升序)
C: 对数组a进行选择排序(升序) D: 对数组a进行选择排序(降序)

正确答案:B

这是一个升序插入排序算法,读完即懂,第 i 次排序时, t=a[i] 作为临时变量保存这一次待插入值, j=i-1 故而 while 循环中 j 是从下标i 的前一项开始向下标 0 遍历,判断 t<a[j] 为真时 a[j+1]=a[j] , j+1 在遍历之初是等于 i 的,也就是将下标 i 位置用前边较大的值覆盖,依次把前边的元素后移,直到a[j] 不大于 t 的时候将 t 插入到下标 j+1 位置,使得前 i 个元素达到有序,方便第i+1 次排序操作,所以第 i 次排序时前边 i-1 个元素都是有序的

考点五:循环嵌套的理解

执行下面的程序段,语句3的执行次数为( )

for(i = 0; i <= n-1; i++) // (1)
for(j = n; j > i; j--) // (2)
state; // (3)

A: n(n+2)/2 B: (n-1)(n+2)/2 C: n(n+1)/2 D: (n-1)(n+2)

正确答案:C

第一次循环有 n 次

当 i=0,第二次循环为 n 次 

当 i=1,第二次循环为 n-1 次

当 i=2,第二次循环为 n-2 次

以此类推,总次数为n+(n-1)+(n-2)+......+2+1,就是个等差数列,等于 n(n+1)/2

编程题

【leetcode 题号:645. 错误的集合】【难度:简单】

集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。

给定一个数组 nums 代表了集合 S 发生错误后的结果。

请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

示例 1:

输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:

输入:nums = [1,1]
输出:[1,2]

题目传送门:OJ链接

解析:

使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置1,表示已经标记出现过,如果哪个数据对应位已经置1,则表示就是重复的数字。有了重复的数字,拿 [1, n] 的总和减去去掉重复数据的数组总和就是丢失的数据。 其实使用标记法时出现的数字对应位每次 ++ ,则最后出现0次的就是丢失,出现2次的就是重复的,这样的方式也可以,不过需要多次遍历。
 

int* findErrorNums(int* nums, int numsSize, int* returnSize){
    *returnSize = 2;
    //遍历nums数组,将其中数据对应的位置1, 哪一位如果已经重置过则意味着数据重复了
    int *arr = (int *)calloc(numsSize + 1, sizeof(int));//申请numsSize个整形空间,并初始化为0
    int *ret = (int *)calloc(*returnSize, sizeof(int));//申请2个整形空间,并初始化为0
    int cur_sum = 0, old_sum = 0;
    for (int i = 0; i < numsSize; i++) {
        if (arr[nums[i]] == 1) { //这个数字在上边数组的对应位置已经置过1了,则重复
            ret[0] = nums[i];//找到重复的数字
        } 
        arr[nums[i]] = 1; //将标记数组的对应数据位置1
        old_sum += i + 1; // 1~n的求和
        cur_sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的)
        }
    ret[1] = old_sum - (cur_sum - ret[0]);//原始总和,减去去掉重复后的当前总和就是丢失的数字
    free(arr);
    return ret;
}

【牛客网题号: OR141 密码检查】【难度:简单】

描述

小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:

1. 密码只能由大写字母,小写字母,数字构成;

2. 密码不能以数字开头;

3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;

4. 密码长度至少为8

现在小明受到了n个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。

输入描述:

输入一个数n,接下来有n(n≤100)行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写字母,小写字母和数字,字符串长度不超过100。

输出描述:

输入n行,如果密码合法,输出YES,不合法输出NO

示例1

输入:

    1
    CdKfIfsiBgohWsydFYlMVRrGUpMALbmygeXdNpTmWkfyiZIKPtiflcgppuR

输出:

    YES

题目传送门:OJ链接

#include <stdio.h>
#include <string.h>
#include <ctype.h>// isdigit   islower isupper 函数包含在ctype.h头文件中
int main()
{
    int n = 0;
    scanf("%d", &n);
    int a = 0;
    int b = 0;
    int c = 0;
    char arr[100] = { 0 };
    for (int i = 0; i < n; i++)
    {
        scanf("%s", &arr);
        if (strlen(arr) < 8)
        {
            printf("NO\n");
            continue;
        }
        if (isdigit(arr[0]) != 0)//判断首字符是否为数字
        {
            printf("NO\n");
            continue;
        }
        for (int j = 0; j < n; j++)
        {
            if (islower(arr[j]) != 0)//判断字符是否为小写字母
                a++;
            if (isupper(arr[j]) != 0)//判断字符是否为大写字母
                b++;
            if(isdigit(arr[j]) != 0)
                c++;
        }
        if(a == sizeof(arr) || b == sizeof(arr) || c == sizeof(arr))
        //全为小写或者大写或者数字
        //至少两种即至多一种取反
        {
            printf("NO\n");
            continue;
        }
        printf("YES\n");
    }
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗小温

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值