题目
开头和结尾都是元音字母(aeiouAEIOU)的字符串为元音字符串,其中混杂的非元音字母数量为其瑕疵度。比如:
“a” 、“aa”是元音字符串,其瑕疵度都为 0
“aiur”不是元音字符串(结尾不是元音字符)
“abira”是元音字符串,其瑕疵度为 2
给定一个字符串,请找出指定瑕疵度的最长元音字符子串,并输出其长度,如果找不到满足条件的元音字符子串,输出 0。
子串:字符串中任意个连续的字符组成的子序列称为该字符串的子串。
输入描述
首行输入是一个整数,表示预期的瑕疵度 flaw,取值范围[0,65535]。
接下来一行是一个仅由字符 a−z 和 A−Z 组成的字符串,字符串长度(0,65535]。
输出描述
输出为一个整数,代表满足条件的元音字符子串的长度。
示例一
输入
0 asdbuiodevauufgh
输出
3
说明
满足条件的最长元音字符子串有两个,分别为 uio
和 auu
,长度为 3。
示例二
输入
2 aeueo
输出
0
说明
没有满足条件的元音字符子串,输出 0
示例三
输入
2 aabeebuu
输出
5
说明
满足条件的最长元音字符子串有两个,分别为aabee
和eebuu
,长度为 5
代码
// 最长的指定瑕疵度的元音子串 #include <stdio.h> #include <string.h> char yuan[] = "aeiouAEIOU"; // 判断是否为元音子串,计算瑕疵度 int isYuan(char *string) { int n = 0; // 瑕疵度 int len = strlen(string); if (strchr(yuan, string[0]) != NULL && strchr(yuan, string[len - 1]) != NULL) { // 开头和结尾都是元音字母 for (int i = 0; i < len; i++) { // strchr,在给定的字符串yuan中查找指定字符string[i]首次出现的位置 if (strchr(yuan, string[i]) == NULL) { // 如果没有出现 n++; // 瑕疵度++ } } } else { n = -1; } return n; } int trans(char *string, int n) { int len = 0; // 满足瑕疵度的子串中最长子串的长度 int length = strlen(string); for (int i = 0; i < length; i++) { for (int j = i + 1; j < length; j++) { char substring[length + 1]; strncpy(substring, string + i, j - i); // string + i: 表示源字符串 string 从第 i+1个字符开始的位置。 // 在C语言中,字符串是一个字符数组,通过加法操作符可以访问数组内的特定位置。这里string + i 实际上是指向 string[i] 后面那个字符的指针。 substring[j - i] = '\0';//注意这里不能省略 int d = isYuan(substring); if (d == n) { // 计算的瑕疵度是否与给定的瑕疵度相同 len = len > strlen(substring) ? len : strlen(substring); } } } return len; } int main() { int flaw; scanf("%d\n", &flaw); char inputString[65536]; fgets(inputString, sizeof(inputString), stdin); int result = trans(inputString, flaw); printf("%d\n", result); return 0; }
总结:
这段代码是用来解决题目中描述的问题的,即寻找给定字符串中最长的瑕疵度为指定值的元音字符串子串,并输出其长度。以下是代码的逐行解释:
- 包含头文件stdio.h和string.h,提供输入输出、字符串处理等相关函数。
- 定义一个包含所有元音字符的数组
yuan
。 - 编写函数
isYuan(char *string)
,该函数接收一个字符串参数,用于判断该字符串是否为元音字符串以及计算其瑕疵度。
- 首先获取字符串长度 len。
- 判断字符串首尾字符是否为元音字符,若是,则继续遍历整个字符串,统计非元音字符数量(即瑕疵度 n);否则,返回-1表示该字符串不是有效的元音字符串。
4.编写函数 trans(char *string, int n),该函数接收一个字符串参数和一个整数参数(预期的瑕疵度),目的是在该字符串中查找瑕疵度为 n 的最长元音子串并返回其长度。
- 获取输入字符串长度 length。
- 使用两层循环遍历所有可能的子串(从 i 到 j 之间的字符组成子串)。
- 创建一个临时子串变量 substring 并复制当前子串到其中。
- 调用 isYuan(substring) 函数检查子串是否为瑕疵度为 n 的元音子串,若是,则更新最长元音子串长度 len。
- 循环结束后返回最长元音子串长度 len。
5.主函数 main():
- 定义一个示例输入字符串
inputString
和期望瑕疵度变量flaw
。 - 调用
trans(inputString, flaw)
函数找到瑕疵度为 flaw 的最长元音子串的长度,并将结果存储在变量result
中。
- 输出结果
result
。
当运行此程序时,它会读取给定字符串 “asdbuiodevauufgh”,期望瑕疵度为0,并最终输出满足条件的最长元音子串的长度。
补充
scanf("%d\n", &flaw);
这其中加&的作用是什么?
&flaw:这里的&是一个取地址运算符,它获取变量flaw的内存地址。因为scanf需要知道应该将读取到的整数值存储在哪里,所以它需要的是目标变量的地址而不是其值。通过传递&flaw,scanf就能把读取到的整数写入到flaw变量所在的内存位置,从而实现对flaw变量的赋值操作。
当你省略了取地址符&时,你传递给scanf的是变量flaw的值(假设为整数类型),而不是它的地址。
- strncpy(substring, string + i, j - i); string + i: 表示源字符串 string 从第 i+1 个字符开始的位置。在C语言中,字符串是一个字符数组,通过加法操作符可以访问数组内的特定位置。这里 string + i 实际上是指向 string[i] 后面那个字符的指针。(在C语言中,数组名可以被视为指向数组首元素(即第一个字符)的指针。)