文章目录
8.判断回文数
【问题描述】
输入一个不超过8位的正整数,判断它是不是回文数。例如,12321是回文数。
【输入形式】
一个正整数
【输出形式】
是回文数
或者
不是回文数
【样例输入1】
123321
【样例输出1】
123321是回文数
#include <stdio.h>
int main() {
int num, reversed = 0, original, remainder;
// 输入正整数
scanf("%d", &num);
// 保存原始输入数值
original = num;
// 反转数字
while (num != 0) {
// 获取最后一位
remainder = num % 10;
// 拼接反转数
reversed = reversed * 10 + remainder;
// 去掉最后一位
num /= 10;
}
// 判断是否是回文数
if (original == reversed) {
printf("%d是回文数\n", original);
} else {
printf("%d不是回文数\n", original);
}
return 0;
}
- scanf(“%d”, &num) 用于输入正整数。
- 通过 while 循环获取每一位数字并构造反转后的数值 reversed。
- 比较原始数字 original 和反转后的数字 reversed,若相等则是回文数。
9. 统计单词数量
【问题描述】
用空格或换行分开的字符串称为单词。输入多行字符串,直到遇到了单词“stop"时才停止。最后输出单词的数量。用于分割单词的空格或换行可能多于1个。单词数量不包括“stop"
【输入形式】
任意多个单词,stop结束
【输出形式】
单词个数【样例输入】
Monday Tuesday Wednesday
Thursday Friday Saturday
Sunday
stop
【样例输出】
7
库函数版本
#include <stdio.h>
#include <string.h>
int main() {
char word[100]; // 用于存储每次输入的一行字符串
int count = 0; // 记录单词数量
// 循环读取输入,直到遇到 "stop"
while (1) {
// 使用 fgets 函数读取一行输入,最大读取 100 个字符
fgets(word, sizeof(word), stdin);
// 去掉输入字符串末尾的换行符
// strcspn(word, "\n") 找到字符串中第一个换行符的位置,然后将其替换成 '\0'
word[strcspn(word, "\n")] = 0;
// 如果输入的是 "stop",则结束输入循环
if (strcmp(word, "stop") == 0) {
break; // 跳出循环
}
// 使用 strtok 函数按空格分割字符串
// strtok 函数会返回指向每个单词的指针,每次调用返回下一个分隔的单词
char *token = strtok(word, " "); // 第一个分割的单词
while (token != NULL) {
count++; // 每找到一个单词就增加计数
token = strtok(NULL, " "); // 获取下一个单词
}
}
// 输出统计的单词数量
printf("%d\n", count);
return 0; // 程序正常结束
}
strcmp:
- if (strcmp(word, “stop”) == 0):strcmp 比较两个字符串,如果相等(即输入为 “stop”),返回 0,程序就会跳出循环并结束输入。
strtok:
- strtok(word, " ");:strtok 函数用于按空格分割字符串。第一次调用时,传入原字符串,它会返回第一个分割出的单词。
- token = strtok(NULL, " ");:后续调用 strtok 时传入 NULL,它会继续处理同一字符串并返回下一个分割出的单词,直到没有更多的单词(返回 NULL)。
非库函数版本
#include <stdio.h>
int main() {
char ch;
int count = 0; // 单词数量
int inWord = 0; // 标志是否在单词中
while (1) {
ch = getchar(); // 读取一个字符
// 判断是否是 's',然后接着读取后续的字符判断是否为 'stop'
if (ch == 's') {
char word[4]; // 用于存储 "stop" 的字符
word[0] = ch;
word[1] = getchar();
word[2] = getchar();
word[3] = getchar();
// 检查是否是 "stop"
if (word[0] == 's' && word[1] == 't' && word[2] == 'o' && word[3] == 'p') {
break; // 如果是 "stop",则退出循环
} else {
// 如果不是 "stop",将读取的字符重新放回输入流
ungetc(word[3], stdin);
ungetc(word[2], stdin);
ungetc(word[1], stdin);
}
}
// 判断是否是单词的开始或结束
if (ch != ' ' && ch != '\n') { // 非空格和换行字符,属于单词的一部分
if (!inWord) { // 如果之前不在单词中,进入一个新的单词
count++;
inWord = 1; // 标记正在单词中
}
} else { // 空格或换行符表示单词的结束
inWord = 0;
}
}
// 输出统计的单词数量
printf("%d\n", count);
return 0;
}
- getchar():使用 getchar() 持续读取字符,直到遇到空格或换行符。
- 判断 “stop”:当检测到输入为字母 ‘s’ 时,我们手动读取接下来的三个字符来判断是否为 “stop”。
- 统计单词:通过判断每次非空格和换行字符的出现时,是否是单词的开始(即进入一个新的单词)。如果之前是空格或换行符,设置 inWord 为 0。
- 跳过空格和换行符:当遇到空格或换行符时,设置 inWord 为 0,表示已经离开当前单词。
1. inWord 变量的定义:
inWord 是一个布尔变量(值为 0 或 1),用于标记程序当前是否处于一个单词的内部。
- inWord = 1:表示程序当前正在读取一个单词。
- inWord = 0:表示程序当前不在单词内(即已经遇到空格或换行符,结束了一个单词)。
2. inWord 的作用:
- inWord 的作用是用来判断和控制是否开始一个新的单词。在逐个字符读取的过程中,空格或换行符被认为是单词的分隔符,因此我们需要判断何时开始一个新单词以及何时结束一个单词。
关键逻辑:
开始一个新单词:
- 当程序读取到一个不是空格和换行的字符(例如字母、数字等),且之前的字符是空格或换行时,表示遇到了一个新的单词。
- 此时,inWord 设置为 1,表示我们现在已经进入了一个新单词。
-结束当前单词:
- 当程序读取到空格或换行符时,表示当前单词的结束。
- 此时,inWord 设置为 0,表示当前不在单词内。
3. 如何使用 inWord 来计算单词数量:
我们通过检查 inWord 的状态来决定是否增加单词的计数器。
-
当 inWord 为 0(之前是空格或换行),且当前字符是字母或数字时,我们认为这是一个新单词的开始,增加单词计数,并将 inWord 设置为 1。
-
当 inWord 为 1(正在处理一个单词)时,程序继续读取字符,直到遇到空格或换行符,此时 inWord 被设置回 0,准备下次读取新的单词。
再优化版本
#include <stdio.h>
int main() {
char ch;
int count = 0; // 单词计数
int inWord = 0; // 标志是否在单词中
while (1) {
ch = getchar(); // 逐个字符读取输入
// 检查是否输入 "stop",如果是则结束
if (ch == 's') {
if (getchar() == 't' && getchar() == 'o' && getchar() == 'p') {
break; // 如果是 "stop",跳出循环
}
}
// 判断字符是否是字母或数字,如果是,则属于一个单词的一部分
if (ch != ' ' && ch != '\n') { // 非空格和换行字符
if (!inWord) { // 如果之前没有进入过单词,说明是一个新的单词
count++; // 增加单词计数
inWord = 1; // 标记已经在单词中
}
} else { // 空格或换行符表示单词结束
inWord = 0; // 标记不在单词中
}
}
// 输出单词数量
printf("%d\n", count);
return 0;
}
10.求数组最大、最小值及平均值
【问题描述】
输入n个(1<n<=10)正整数并保存到一个数组中,求出最大值、最小值、平均值(保留2位小数),以及最大值、最小值在数组中的下标分别是多少。
【输入形式】
共输入2行
第1行输入整数的个数n
第2行输入n个整数,用空格分隔
【输出形式】
需要输出5行
第1行输出最大值
第2行输出最大值的下标
第3行输出最小值
第4行输出最小值的下标
第5行输出平均值
#include <stdio.h>
int main() {
int n;
// 输入整数的个数
scanf("%d", &n);
int arr[n]; // 定义一个数组来保存输入的整数
int max, min, max_index, min_index;
int sum = 0;
// 输入 n 个整数
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 初始值设为数组的第一个元素
max = min = arr[0];
max_index = min_index = 0;
// 遍历数组,计算最大值、最小值以及它们的下标
for (int i = 0; i < n; i++) {
sum += arr[i]; // 累加总和
// 查找最大值和最小值
if (arr[i] > max) {
max = arr[i];
max_index = i;
}
if (arr[i] < min) {
min = arr[i];
min_index = i;
}
}
// 输出最大值
printf("%d\n", max);
// 输出最大值的下标
printf("%d\n", max_index);
// 输出最小值
printf("%d\n", min);
// 输出最小值的下标
printf("%d\n", min_index);
// 输出平均值,保留两位小数
printf("%.2f\n", (float)sum / n);
return 0;
}
- scanf(“%d”, &n); 用来读取整数的个数。
- scanf(“%d”, &arr[i]); 用来读取每个整数并存储到数组 arr 中。
11.求矩阵各行元素之和
【问题描述】
输入m,n 和一个m*n矩阵(最大为10 x10),求他们的各行元素之和。
【输入形式】
第一行输入m和n的值
然后输入m行n列的矩阵【输出形式】
每行元素之和,共m行【样例输入】
2 3
1 2 3
4 5 6
【样例输出】
第0行元素之和是6
第1行元素之和是15
#include <stdio.h>
int main() {
int m, n;
// 输入矩阵的行数和列数
scanf("%d %d", &m, &n);
int matrix[m][n]; // 定义一个 m x n 的矩阵
// 输入矩阵的元素
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &matrix[i][j]);
}
}
// 计算并输出每行元素之和
for (int i = 0; i < m; i++) {
int row_sum = 0; // 记录当前行的元素和
for (int j = 0; j < n; j++) {
row_sum += matrix[i][j]; // 累加当前行的每个元素
}
printf("第%d行元素之和是%d\n", i, row_sum); // 输出当前行的元素和
}
return 0;
}
1. 输入:
- scanf(“%d %d”, &m, &n);:首先读取矩阵的行数 m 和列数 n。
- scanf(“%d”, &matrix[i][j]);:逐个读取矩阵的元素,并存储到 matrix 二维数组中。
2. 计算每行元素之和:
- int row_sum = 0;:每次计算新的一行时,初始化 row_sum 为 0。
- 在内部的 for 循环中,逐个累加每行的元素。
3. 输出:
- printf(“第%d行元素之和是%d\n”, i, row_sum);:输出当前行的和。
12.求字符串长度
【问题描述】
任意输一行字符串(包括空格),求其长度(不用strlen函数)
【输入形式】
任意一个字符串【输出形式】
长度
【样例输入】
abcd efg
【样例输出】
8
#include <stdio.h>
int main() {
char str[100]; // 定义一个数组保存输入字符串
int length = 0; // 初始化长度为0
// 输入一行字符串,包括空格
fgets(str, sizeof(str), stdin);
// 手动计算字符串长度
while (str[length] != '\0' && str[length] != '\n') {
length++; // 每读取一个字符,长度加1
}
// 输出字符串长度
printf("%d\n", length);
return 0;
}
1. 输入字符串:
- 使用 fgets 函数读取一整行字符串,包括空格。
- fgets(str, sizeof(str), stdin):从标准输入读取一行,存储到 str 中,最多读取 sizeof(str) - 1 个字符。
2. 计算长度:
- 从索引 0 开始,遍历字符串,直到遇到字符串结束标志 ‘\0’。
- 如果 fgets 读取到换行符 ‘\n’,我们也停止计数,因为换行符不是字符串内容的一部分。
3. 输出长度:
- 打印结果 length。
13.连接两行字符串
【问题描述】
任意输入两行字符串,把第二行字符串连接到第一行字符串末尾(不用strcat函数)
【输入形式】
共2行,每行一个字符串(含空格)【输出形式】
连接后的字符串【样例输入】
abcd
efg
【样例输出】
abcdefg
#include <stdio.h>
int main() {
char str1[200]; // 用于存储第一行字符串,大小足够容纳拼接结果
char str2[100]; // 用于存储第二行字符串
int i = 0, j = 0;
// 输入第一行字符串
fgets(str1, sizeof(str1), stdin);
// 输入第二行字符串
fgets(str2, sizeof(str2), stdin);
// 手动计算第一行字符串的末尾位置
while (str1[i] != '\0' && str1[i] != '\n') {
i++; // 移动到第一行字符串的末尾
}
// 将第二行字符串逐字符连接到第一行的末尾
while (str2[j] != '\0' && str2[j] != '\n') {
str1[i] = str2[j];
i++;
j++;
}
// 添加字符串结束标志
str1[i] = '\0';
// 输出连接后的字符串
printf("%s\n", str1);
return 0;
}
1. 输入部分:
- 使用 fgets 读取两行字符串到 str1 和 str2。
- fgets 会自动在字符串末尾添加 ‘\0’,但可能会包含换行符 ‘\n’,需要跳过它。
2. 计算第一行字符串的末尾:
- 遍历 str1 找到其末尾位置(即 ‘\0’ 或 ‘\n’ 之前的索引)。
3. 拼接字符串:
- 遍历 str2,将每个字符复制到 str1 的末尾位置。
4. 手动添加字符串结束标志:
- 在拼接完毕后,将 ‘\0’ 添加到 str1 的末尾。
14.删除特定字符后的所有字符
【问题描述】
输入一个字符串和一个特定字符,在字符串中剧除从该特定字符开始的所有字符。
【翰入形式】
共2行
第1行输入任意一个字符串(含空格)
第2行输入一个特定字符
【输出形式】
规除特定字符后的字符串是
【样例输入1】
abcdefg
【样例输出1】
特定字符是d
规除特定字符d后的字符串是abc
#include <stdio.h>
int main() {
char str[200]; // 用于存储输入的字符串
char target; // 用于存储特定字符
int i = 0; // 遍历字符串的索引
// 输入字符串
fgets(str, sizeof(str), stdin);
// 输入特定字符
scanf(" %c", &target); // 注意前面的空格以忽略换行符
// 查找特定字符的位置
while (str[i] != '\0') {
if (str[i] == target) {
str[i] = '\0'; // 将特定字符位置设置为字符串结束标志
break; // 找到后立即停止
}
i++;
}
// 输出结果
printf("特定字符是%c\n", target);
printf("删除特定字符%c后的字符串是%s\n", target, str);
return 0;
}
1. 输入部分:
- 使用 fgets 输入字符串,可以包含空格。
- 使用 scanf 输入特定字符,注意格式 " %c",空格用于跳过换行符。
2. 查找特定字符:
- 使用 while 循环遍历字符串,检查每个字符是否等于目标字符。
- 如果找到目标字符,将该位置设为字符串结束标志 ‘\0’,然后终止循环。
3. 截断字符串:
- 一旦找到特定字符,后面的部分就会被截断,字符串只保留到特定字符之前。
15.自n处抽取字符串中m个字符
【问题描述】
编写程序,从输入的一行字符串中抽取一部分(从第n个字符开始抽取m个字符)构成一个新的字符串,并输出。n>0且n<=字符串的长度,否则提示起始位置-n-越界。
要求:n和m都由用户输入。
如果抽取的字符串长度不够,则按照实际长度抽取,例如,字符串为“abcde”,若n=2,m=3,则抽取结果为“bcd";若n=3,m=5,则抽取结果为“cde”;若n=0,m=4 则输出:起始位置0越界若n=6,m=2 则输出:起始位置6越界
【输入形式】
共3行
第1行任意输入一个字符串(含空格)
第2行输入n的值
第3行输入m的值
【输出形式】
抽取的新字符串
或者
起始位置n越界
#include <stdio.h>
#include <string.h>
int main() {
char str[200]; // 输入的原字符串
char result[200]; // 存储抽取后的字符串
int n, m; // 起始位置和抽取的字符数
int length; // 字符串的实际长度
// 输入字符串
fgets(str, sizeof(str), stdin);
// 去掉字符串末尾的换行符
str[strcspn(str, "\n")] = '\0';
// 输入起始位置n和抽取字符数m
scanf("%d", &n);
scanf("%d", &m);
// 获取字符串的长度
length = strlen(str);
// 检查起始位置是否越界
if (n <= 0 || n > length) {
printf("起始位置%d越界\n", n);
return 0;
}
// 计算实际可抽取的字符数
int extract_length = (n - 1 + m <= length) ? m : (length - (n - 1));
// 抽取字符串
for (int i = 0; i < extract_length; i++) {
result[i] = str[n - 1 + i]; // n-1是实际索引
}
result[extract_length] = '\0'; // 添加字符串结束标志
// 输出结果
printf("抽取的新字符串是%s\n", result);
return 0;
}
- 输入部分:
- 使用 fgets 读取字符串,同时去掉可能的换行符。
- 使用 scanf 输入起始位置 n 和抽取长度 m。
- 检查起始位置是否越界:
- 起始位置 n 应满足 1 <= n <= length。
- 如果 n 越界,输出错误提示并结束程序。
- 计算实际抽取长度:
- 如果从第 n 个字符开始的剩余字符数小于 m,则实际抽取长度为剩余字符数。
- 否则,抽取长度为 m。
- 抽取字符:
- 通过循环将从 str[n-1] 开始的字符复制到 result 数组中。
- 在结果字符串的末尾添加 \0 表示结束。
16.计算主对角线元素之和
【问题描述】输入一个4行4列的单精度数组,计算主对角线元素之和,保留1位小数输出。
【翰入形式】
4行4列单精度数据,数据之间用空格分隔
【翰出形式】
主对角线元素之和
【样例输入】
1.5 2.1 3.4 8.5
5.6 36 9923
3.5 1.6 8.5 7.6
1.0 22 34 5.6
【样例输出】
19.2
#include <stdio.h>
int main() {
float matrix[4][4]; // 定义一个 4x4 单精度矩阵
float sum = 0.0; // 初始化主对角线元素的和为 0.0
// 输入矩阵元素
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
scanf("%f", &matrix[i][j]);
}
}
// 计算主对角线元素之和
for (int i = 0; i < 4; i++) {
sum += matrix[i][i]; // 主对角线元素的条件是 i == j
}
// 输出结果,保留 1 位小数
printf("%.1f\n", sum);
return 0;
}
17.数组合并
【问题描述]
分别输入两个长度为5的从小到大排好序的整数数组,将这两个数组合并到第三个数组中,保持从小到大的排序,并输出。
【输入形式】
共2行,每行5个整数,数据之间用空格分隔
【输出形式】
从小到大输出合并后的数组值,每个整数后面用一个空格进行分隔
【样例输入】
13579
02468
【样例输出】
0123456789
#include <stdio.h>
int main() {
int arr1[5], arr2[5], merged[10];
int i = 0, j = 0, k = 0;
// 输入第一个数组
for (i = 0; i < 5; i++) {
scanf("%d", &arr1[i]);
}
// 输入第二个数组
for (i = 0; i < 5; i++) {
scanf("%d", &arr2[i]);
}
// 合并两个数组
i = 0; j = 0; // 初始化两个数组的索引
while (i < 5 && j < 5) {
if (arr1[i] < arr2[j]) {
merged[k++] = arr1[i++]; // 将 arr1[i] 放入结果数组
} else {
merged[k++] = arr2[j++]; // 将 arr2[j] 放入结果数组
}
}
// 如果 arr1 有剩余元素,追加到结果数组
while (i < 5) {
merged[k++] = arr1[i++];
}
// 如果 arr2 有剩余元素,追加到结果数组
while (j < 5) {
merged[k++] = arr2[j++];
}
// 输出合并后的数组
for (i = 0; i < 10; i++) {
printf("%d ", merged[i]);
}
printf("\n");
return 0;
}
合并逻辑:
- 初始化两个索引 i 和 j,分别指向 arr1 和 arr2 的开头。
- 逐个比较两个数组的当前元素,将较小的元素放入 merged 数组。
- 如果一个数组被全部合并,直接将另一个数组的剩余部分追加到 merged 中。
18.统计数组中出现频率最高的数
【问题描述】
任意读入10个整数存放到数组a中,统计数组中出现频率最高的数,特出该数及其出现次数。
如果数组中没有重复出现的数,则输出"没有重复出现的数”;如果有多个频率最好的数字,按照输入的先后顺序全部输出,参考下的程序运行示例。
【输入形式】
10个整数,数据之间用空格分隔
【输出形式】
共2行
第1行输出a数组中的数据,每个数据后面用1个空格进行分隔第2行输出出现频率最高的数和出现次数
【样例输入】
11 22 33 33 44 55 66 77 88 99
【样例输出】
a数组元素为:11 22 33 33 44 55 66 77 88 99数组a中出现频率最高的数是33,出现次数为2
思路:
- 使用一个辅助数组 freq 来记录每个数的出现次数。
- 遍历数组,更新每个数的出现次数。
- 找出频率最高的次数及对应的数。
- 如果有多个数频率最高,则按照输入顺序依次输出。
#include <stdio.h>
int main() {
int a[10]; // 用于存储输入的数组
int freq[10] = {0}; // 用于存储每个数的出现次数
int i, j;
int max_freq = 1; // 记录最高出现次数,初始值为 1
int has_duplicates = 0; // 标记是否存在重复的数字
// 输入 10 个整数
for (i = 0; i < 10; i++) {
scanf("%d", &a[i]);
}
// 输出数组元素
printf("a数组元素为:");
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
printf("\n");
// 统计每个数的出现次数
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
if (a[i] == a[j]) {
freq[i]++;
}
}
// 更新最高频率
if (freq[i] > max_freq) {
max_freq = freq[i];
has_duplicates = 1; // 存在重复数字
}
}
// 输出结果
if (max_freq == 1) {
printf("没有重复出现的数\n");
} else {
printf("数组a中出现频率最高的数是:");
for (i = 0; i < 10; i++) {
if (freq[i] == max_freq) {
printf("%d,", a[i]);
freq[i] = 0; // 避免重复输出相同数
}
}
printf("出现次数为%d\n", max_freq);
}
return 0;
}
1. 输入和输出数组:
- 输入 10 个整数存入数组 a。
- 使用 printf 输出数组的所有元素。
2. 统计频率:
- 使用双重循环比较数组中的每个元素,计算它的出现次数,并存入 freq 数组。
- 内层循环对每个元素进行比较,如果找到相同的值,则相应位置的频率值加 1。
3. 确定最高频率:
- 每次更新 freq 时,比较其值是否大于当前的 max_freq,如果是,则更新 max_freq。
- 同时通过标志变量 has_duplicates 确认是否存在重复数字。
4. 输出结果:
- 如果最高频率为 1,则说明所有数字没有重复。
- 如果存在最高频率,遍历 freq,输出所有频率等于 max_freq 的数。
祝小丢丢学有所成