C语言练习题
目一 :输出一段单词中最后一个单词的长度
描述
对于给定的若干个单词组成的句子,每个单词均由大小写字母混合构成,单词间使用单个空格分隔。输出最后一个单词的长度。
输入描述:
在一行上输入若干个字符串,每个字符串代表一个单词,组成给定的句子。
除此之外,保证每个单词非空,由大小写字母混合构成,且总字符长度不超过 10^3 。
输出描述:
在一行上输出一个整数,代表最后一个单词的长度。
思路
- 使用 fgets() 读取整行输入,包括空格
- 从字符串末尾开始向前遍历
- 跳过末尾可能存在的换行符和空格
- 找到最后一个单词的起始位置
- 统计最后一个单词的长度,直到遇到空格或字符串结束
- 输出结果
#include<stdio.h>
#include<string.h>int main()
{char sentence[1001];fgets(sentence,sizeof(sentence),stdin);//获取字符串int len = strlen(sentence);//得到字符串长度int count = 0;//跳过末尾的换行符if(len >0 && sentence[len - 1] == '\n'){sentence[len -1] = '\0';len--;}//从后往前便利数组,找到空格处,为最后一个单词,并进行计数for(int i = len - 1;i >=0;i--){if(sentence [i] != ' ')//不为空格进行计数{count++;}else{break;//调出循环}}printf("%d \n",count);return 0;
}

题目二
描述
对于给定的由大小写字母、数字和空格混合构成的字符串 s,给定字符 c,按要求统计:
若 c 为大写或者小写字母,统计其大小写形态出现的次数和;
若 c 为数字,统计其出现的次数。
保证字符 c 要么为字母、要么为数字。
输入描述:
第一行输入一个长度 1≦length(s)≦10^3,由大小写字母、数字和空格构成的字符串 s。保证首尾不为空格。
第二行输入一个字符 c,保证 c 为大小写字母或数字。
输出描述:
在一行上输出一个整数,代表统计结果。
思路
- 使用fgets读取一行字符串,包括空格,直到换行符。
- 使用scanf(" %c", &c)读取字符c,前面的空格可以跳过换行符。
- 计算字符串s的长度(不包括换行符,如果有的话,我们可以将换行符替换为’\0’)。
- 初始化计数器count=0。
- 如果c是字母(isalpha©),则遍历字符串s,对于每个字符,如果它是字母,并且将其转换为小写后等于c的小写形式,则计数。
- 如果c是数字(isdigit©),则遍历字符串s,对于每个字符,如果等于c,则计数。
注意:我们使用<ctype.h>中的函数,如isalpha, isdigit, tolower等。
#include<stdio.h>
#include<string.h>
#include<ctype.h>int main()
{char s[1001];char c;fgets(s,sizeof(s),stdin);//获取字符串s[strcspn(s,"\n")] = '\0';//去掉末尾的换行符scanf(" %c",&c);//获取字符c,注意%s前的空格int count = 0;int len = strlen(s);//根据字符c来进行统计if(isalpha(c)){char upper_c = toupper(c);char lower_c = tolower(c);for(int i = 0;i < len;i++){if(s[i] == upper_c || s[i] == lower_c){count++;}}}else{//c是数字for(int i = 0;i < len;i++){if(s[i] == c){count++;}}}printf("%d \n",count);return 0;
}

题目三
描述
对于明明生成的 n 个 1 到 500 之间的随机整数,你需要帮助他完成以下任务:
删去重复的数字,即相同的数字只保留一个,把其余相同的数去掉;
然后再把这些数从小到大排序,按照排好的顺序输出。
你只需要输出最终的排序结果。
输入描述:
第一行输入一个整数 n(1≦n≦1000),代表明明生成的数字个数。
此后 n 行,第 i 行输入一个整数 a_i (1≦a_i≦500),代表明明生成的随机整数。
输出描述:
输出若干行,每行输出一个整数,代表输入数据排序后的结果。第一行输出最小的数字。
#include<stdio.h>int main()
{int n ;scanf("%d",&n);//创建一个标记数组,用于记录数字是否出现过int flag[501] = {0};int num ;//用于接收输入的数字//读取并标记for(int i = 0;i < n;i++){scanf("%d",&num);flag[num] = 1;//将接收的数据作为下标放到指定位置,并进行标记}//输出结果(从小到大)for(int i = 1;i <= 500;i++){if(flag[i] == 1){printf("%d\n",i);}}return 0;
}

题目四
描述
对于给定的由小写字母和数字混合构成的字符串 s,你需要按每 8 个字符换一行的方式书写它,具体地:
书写前 8 个字符,换行;
书写接下来的 8 个字符,换行;
……
重复上述过程,直到字符串被完全书写。
特别地,如果最后一行不满 8 个字符,则需要在字符串末尾补充 0,直到长度为 8。
输入描述:
在一行上输入一个长度 1≦length(s)≦100,由小写字母和数字构成的字符串 s。
输出描述:
输出若干行,每行输出 8 个字符,代表按题意书写的结果。

#include <stdio.h>
#include<string.h>
int main()
{char s[101];//读取字符串scanf("%s",&s);int len = strlen(s);int index = 0;//按每8个字符一行输出while(index < len){for(int i = 0;i < 8;i++){if(index + i < len){printf("%c",s[index+i]);}else{printf("0");}}printf("\n");index += 8;}return 0;
}

题目五
描述
对于给定的十六进制数,输出其对应的十进制表示。
在本题中,十六进制数的格式为:“0x” 开头,后跟若干个十六进制数字(保证为 “0-9” 和 “A-F” 中的一个)。其中,“A-F” 依次代表十进制中的 10∼15。
输入描述:
在一行上输入一个十六进制数 s,代表待转换的十六进制数,格式见题干。保证 s 转化得到的十进制数 x 的范围为 1≦x<2^31。
输出描述:
在一行上输出一个整数,代表 s 对应的十进制数。

#include<stdio.h>
#include<string.h>
#include<ctype.h>int main()
{char hex[20];scanf("%s",&hex);int len = strlen(hex);long long decimal = 0;//使用long long防止溢出//跳过"0x"前缀int start = 2;for(int i = start;i < len;i++){char c = hex[i];int digit = 0;if(isdigit(c)){digit = c - '0';}else{//将字母转化为大写(处理小写字母的情况)c = toupper(c);digit = c - 'A' + 10;}decimal = decimal *16 + digit;}printf("%lld\n",decimal);return 0;
}

题目六
描述
对于给定的整数 n,从小到大依次输出它的全部质因子。即找到这样的质数 p_1,p_2,⋯" ",p_k,使得 n=p_1×p_2×⋯×p_k。
输入描述:
在一行上输入一个整数 n(2≦n≦2×10^9+14) 代表待分解的整数。
输出描述:
在一行上从小到大输出若干个整数,代表 n 的质因子。
#include <stdio.h>int main() {long long n;scanf("%lld", &n);long long original_n = n;int first = 1; // 用于控制输出格式// 处理因子2while (n % 2 == 0) {if (!first) {printf(" ");}printf("%d", 2);n /= 2;first = 0;}// 处理奇数因子for (long long i = 3; i * i <= n; i += 2) {while (n % i == 0) {if (!first) {printf(" ");}printf("%lld", i);n /= i;first = 0;}}// 处理剩余的质数if (n > 1) {if (!first) {printf(" ");}printf("%lld", n);}printf("\n");return 0;
}

题目七
描述
对于给定的正实数 x,输出其四舍五入后的整数。更具体地说,若 x 的小数部分大于等于 0.5,则输出向上取整后的整数;否则输出向下取整后的整数。
【提示】
不同编译器版本、不同系统环境对待实数的精度处理不同,我们建议您使用在线编译器进行调试。
输入描述:
输入一个小数点后位数不超过 5 位的实数 x(0<x≦20)。保证实数不存在前导零和后导零。
输出描述:
在一行上输出一个整数,代表 x 四舍五入后的结果。
#include <stdio.h>int main() {double x;scanf("%lf", &x);// 方法2:手动实现四舍五入int result;// 将小数部分乘以10,检查第一位小数double decimal_part = x - (int)x;if (decimal_part >= 0.5) {result = (int)x + 1; // 向上取整} else {result = (int)x; // 向下取整}printf("%d\n", result);return 0;
}

题目八
描述
数据表中,一条记录包含表索引和数值两个值。请对表索引相同的记录进行合并(即将相同索引的数值进行求和运算),随后按照索引值的大小从小到大依次输出。
输入描述:
第一行输入一个整数 n(1≦n≦500) 代表数据表的记录数。
此后 n 行,第 i 行输入两个整数 x_i,y_i (0≦x_i≦11" " 111" " 111;" " 1≦y_i≦10^5) 代表数据表的第 i 条记录的索引和数值。
输出描述:
一共若干行(视输入数据变化),第 i 行输出两个整数,代表合并后数据表中第 i 条记录的索引和数值。

#include<stdio.h>
#include<stdlib.h>#define MAX_INDEX 1111112int main()
{int n;scanf("%d",&n);//使用数组存储每个索引的累计值long long *hash =(long long *) calloc(MAX_INDEX,sizeof(long long));//读取并累加记录for(int i = 0;i < n;i++){int index;long long value;scanf("%d %lld",&index,&value);hash[index] += value;}//输出非零索引的记录for(int i = 0;i < MAX_INDEX;i++){if(hash[i] != 0){printf("%d %lld \n",i,hash[i]);}}free(hash);return 0;
}
题目九
描述
对于给定的正整数 n ,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。具体地,如果遇到相同数字,保留在最右侧出现的第一个数字。
输入描述:
在一行上输入一个整数 n(1≦n≦10^8) 代表给定的整数。保证 n 的最后一位不为 0 。
输出描述:
在一行上输出一个整数,代表处理后的数字。

#include<stdio.h>int main()
{int n;scanf("%d",&n);int used[10] = {0};//初始化一个数组来跟踪数字0-9是否出现过while(n > 0){int digit = n%10;//获取当前最低位数字if(!used[digit])//当前数字在数组中没有出现{used[digit] = 1;//标记一下,现在出现了printf("%d",digit);//输出该数组}n /= 10;//移除已处理的最低位}printf("\n");return 0;}
题目十
描述
对于给定的字符串,统计其中的 ASCII 码在 0 到 127 范围内的不同字符的个数。
备注:受限于输入,本题实际输入字符集为 ASCII 码在 33 到 126 范围内的可见字符。您可以参阅下表获得其详细信息(您可能关注的内容是,这其中不包含空格、换行)。
输入描述:
输入一个长度 1≦length(s)≦500,仅由图片中的可见字符构成的字符串 s。
输出描述:
在一行上输出一个整数,代表给定字符串中 ASCII 码在 0 到 127 范围内的不同字符的个数。

逻辑

#include <stdio.h>
#include <string.h>int main() {char s[510];int used[128] = {0};int count = 0;fgets(s, sizeof(s), stdin);for (int i = 0; s[i] != '\0' && s[i] != '\n'; i++) {unsigned char c = s[i];if (c < 128 && !used[c]) {used[c] = 1;count++;}}printf("%d\n", count);return 0;
}
