6-1 | 使用函数实现字符串部分复制 |
6-2 | 删除字符 |
6-3 | 字符串的连接 |
6-4 | 函数实现字符串逆序 |
6-5 | 指定位置输出字符串 |
6-6 | 查找子串 |
7-1 | 找最小的字符串 |
7-2 | 字符串排序 |
7-3 | 找最长的字符串 |
7-4 | A-B |
6-1 使用函数实现字符串部分复制
本题要求编写函数,将输入字符串 t 中从第 m 个字符开始的全部字符复制到字符串 s 中。
函数接口定义:
void strmcpy( char *t, int m, char *s );
函数strmcpy
将输入字符串char *t
中从第 m
个字符开始的全部字符复制到字符串char *s
中。若 m
超过输入字符串的长度,则结果字符串应为空串。
void strmcpy(char *t, int m, char *s)
{
// 因为s本来就是空的,所以直接返回,s就是空字符串
if (!t) return; // t 如果是空的,直接返回
while (m > 1) // 从 1 开始
{
if (*t == '\0') return; // m 大于 t 的长度了,直接返回
--m;
++t;
}
while (*t != '\0') *(s++) = *(t++);
*s = '\0';
}
6-2 删除字符
本题要求实现一个删除字符串中的指定字符的简单函数。
函数接口定义:
void delchar( char *str, char c );
其中char *str
是传入的字符串,c
是待删除的字符。函数delchar
的功能是将字符串str
中出现的所有c
字符删除。
解:
常规做法有两种:
- 从前往后遍历字符串,如果是要删除的就把后边所有的前移一位
- 从前往后遍历字符串,把要保留的部分放到一个新的字符串数组中,再赋值会给 str
第一个方法不需要额外的空间,但是如果要删除的字符出现的次数很多的话,会非常非常慢,所以我用的第二种,同时还要考虑极端情况(没有要删除的、全是要删除的、str字符串长度超过 MAXN)。
void delchar(char *str, char c)
{
if (!str) return;
char tmp[201]; // 21不够长
char *tHead = tmp, *tStr = str;
int foundc = 0;
while (*tStr != '\0')
{
if (*tStr == c)
{
++tStr;
foundc = 1;
}
else
*(tHead++) = *(tStr++);
}
if(foundc == 0) return ; // 没有要删除的就直接返回
if(tHead == tmp) // 字符串中全都是字符 c,也就是删除之后都没了
{
*str = '\0';
return;
}
tStr = str;
tHead = tmp;
while (*tHead != '\0')
*tStr++ = *tHead++;
*tStr = '\0';
}
6-3 字符串的连接
本题要求实现一个函数,将两个字符串连接起来。
函数接口定义:
char *str_cat( char *s, char *t );
函数str_cat
应将字符串t
复制到字符串s
的末端,并且返回字符串s
的首地址。
char* str_cat(char* s, char* t)
{
char* tmps = s;
while(*tmps != '\0') ++tmps;
while(*t != '\0') *tmps++ = *t++;
*tmps = '\0';
return s; // 最后要返回 s 的首地址
}
6-4 函数实现字符串逆序
函数接口定义:
void f( char *p );
函数f
对p
指向的字符串进行逆序操作。要求函数 f
中不能定义任何数组,不能调用任何字符串处理函数。
解:
既然不让定义数组,那肯定就是要在 p 这个字符串数组自身中交换元素,达到逆序效果,所以需要先得到字符串长度,然后对着交换对应元素就行。
void f(char *p)
{
char* tmp = p;
int len = 0;
while(*tmp != '\0') // 得到的 len 是不包括 '\0' 的长度
{
++tmp;
++len;
}
for(int i = 0; i < len / 2; i++) // 不需要 <=
{
char t = p[i];
p[i] = p[len - 1 - i];
p[len - 1 - i] = t;
}
p[len] = '\0';
}
6-5 指定位置输出字符串
本题要求实现一个函数,对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符。
函数接口定义:
char *match( char *s, char ch1, char ch2 );
函数match
应打印s
中从ch1
到ch2
之间的所有字符,并且返回ch1
的地址。
char* match(char* s, char ch1, char ch2)
{
char *tmps1 = s;
while (*tmps1 != ch1)
{
if (*tmps1 == '\0') // 没有找到ch1,直接返回
{
printf("\n");
char* ret = "\0";
return ret; // 必须这样才能过第二个测试点
}
++tmps1;
}
// 循环结束 tmps1 就是 ch1 的位置
char *tmps1res = tmps1;
while (*tmps1 != '\0')
{
printf("%c", *tmps1++);
if (*tmps1 == ch2)
{
printf("%c\n", ch2);
return tmps1res;
}
}
printf("\n");
return tmps1res;
}
6-6 查找子串
本题要求实现一个字符串查找的简单函数。
函数接口定义:
char *search( char *s, char *t );
函数search
在字符串s
中查找子串t
,返回子串t在s
中的首地址。若未找到,则返回NULL。
char* search(char *s, char *t)
{
char* tmps = s;
while(1)
{
if(*tmps == '\0') return NULL;
if(*tmps == *t)
{
char *res = tmps, *tmpt = t;
while(1)
{
++tmps;
++tmpt;
if(*tmpt == '\0') return res; // 把t匹配完了都是对的,那就是找到了
if(*tmps == '\0' || *tmpt == '\0' || *tmps != *tmpt) break;
}
}
++tmps;
}
}
7-1 找最小的字符串
本题要求编写程序,针对输入的N个字符串,输出其中最小的字符串。
输入格式:
输入第一行给出正整数N;随后N行,每行给出一个长度小于80的非空字符串,其中不会出现换行符,空格,制表符。
输出格式:
在一行中用以下格式输出最小的字符串:
Min is: 最小字符串
输入样例:
5
Li
Wang
Zha
Jin
Xian
输出样例:
Min is: Jin
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
char ch[n][81];
for(int i = 0; i < n; i++) scanf("%s", ch[i]);
int min_idx = 0;
for(int i = 1; i < n; i++)
for(int j = 0; j < 81; j++)
{
if(ch[i][j] > ch[min_idx][j])
break;
if(ch[i][j] < ch[min_idx][j] || (ch[i][j] == '\0' && ch[min_idx][j] != '\0'))
{
min_idx = i;
break;
}
}
printf("Min is: %s\n", ch[min_idx]);
return 0;
}
7-2 字符串排序
本题要求编写程序,读入5个字符串,按由小到大的顺序输出。
输入格式:
输入为由空格分隔的5个非空字符串,每个字符串不包括空格、制表符、换行符等空白字符,长度小于80。
输出格式:
After sorted:
每行一个字符串
输入样例:
red yellow blue green white
输出样例:
After sorted:
blue
green
red
white
yellow
解:
下面这个是没有用 strlen、strcmp、strcpy 的方法。
#include <stdio.h>
int main()
{
char ch[5][81];
char c;
// 读取五个字符串 (scanf("%s") 遇空格停止)
for(int i = 0; i < 5; i++)
scanf("%s", ch[i]);
int flag[5] = { 1, 1, 1, 1, 1 }; // 1表示没有输出过,0表示输出过了
printf("After sorted:\n");
for(int i = 0; i < 5; i++) // 共输出5次,每次选最小的,并让对应flag为0
{
int min_idx = -1;
for(int j = 0; j < 5; j++)
{
if (flag[j] == 0) continue;
if (min_idx == -1)
{
min_idx = j;
continue;
}
for (int t = 0; t < 81; t++)
{
if (ch[min_idx][t] == '\0')
break;
if(ch[j][t] == '\0' || ch[j][t] < ch[min_idx][t])
{
min_idx = j;
break;
}
if (ch[j][t] > ch[min_idx][t])
break;
}
}
printf("%s\n", ch[min_idx]); // 输出最小的字符串
flag[min_idx] = 0;
}
return 0;
}
用string.h中的函数就会简单一些。
#include <stdio.h>
#include <string.h>
int main()
{
char ch[5][81];
char c;
// 读取五个字符串
for(int i = 0; i < 5; i++)
scanf("%s", ch[i]);
int flag[5] = { 1, 1, 1, 1, 1 }; // 1表示没有输出过,0表示输出过了
printf("After sorted:\n");
for(int i = 0; i < 5; i++) // 共输出5次,每次选最小的,并让对应flag为0
{
int min_idx = -1;
for(int j = 0; j < 5; j++)
{
if (flag[j] == 0) continue;
if (min_idx == -1)
{
min_idx = j;
continue;
}
// 比较两个字符串大小
if(strcmp(ch[j], ch[min_idx]) < 0)
min_idx = j;
}
printf("%s\n", ch[min_idx]); // 输出最小的字符串
flag[min_idx] = 0;
}
return 0;
}
7-3 找最长的字符串
本题要求编写程序,针对输入的N个字符串,输出其中最长的字符串。
输入格式:
输入第一行给出正整数N;随后N行,每行给出一个长度小于80的非空字符串,其中不会出现换行符,空格,制表符。
输出格式:
在一行中用以下格式输出最长的字符串:
The longest is: 最长的字符串
如果字符串的长度相同,则输出先输入的字符串。
输入样例:
5
li
wang
zhang
jin
xiang
输出样例:
The longest is: zhang
#include <stdio.h>
#include <string.h>
int main()
{
int n, max_len = 0, max_idx = -1;
scanf("%d", &n);
char ch[n][81];
for(int i = 0; i < n; i++)
{
scanf("%s", ch[i]);
if(strlen(ch[i]) > max_len)
{
max_len = strlen(ch[i]);
max_idx = i;
}
}
printf("The longest is: %s\n", ch[max_idx]);
return 0;
}
7-4 A-B
本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。
输入格式:
输入在2行中先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出A−B的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
#include <stdio.h>
#include <string.h>
int main()
{
int i= 0;
char a[10001], b[10001], res[10001], ch;
while((a[i] = getchar()) != '\n')
++i;
a[i] = '\0';
i = 0;
while((b[i] = getchar()) != '\n')
++i;
b[i] = '\0';
int cur = 0;
for(i = 0; a[i] != '\0'; i++)
{
int isfound = 0;
for(int j = 0; b[j] != '\0'; j++)
if(a[i] == b[j])
{
isfound = 1;
break;
}
if(isfound == 0)
res[cur++] = a[i];
}
res[cur] = '\0';
printf("%s\n", res);
return 0;
}