Problem Description
输入两个字符串,分别为模式串和文本串。若模式串是文本串的子字符串,则要求将文本串中的子字符串删除,并返回删除子字符串后的字符串。
Input
首先输入模式串,然后输入文本串。(均由大写或者小写字母构成,二者以空格为间隔隔开)
Output
若模式串是文本串的子字符串,输出删除子字符串后的字符串。
若模式串不是文本串的子字符串,输出-1。
Sample Input
dfg asdfghj
Sample Output
ashj
解题思路
- 利用strstr()函数得到模式串在文本串中的起始位置。
- 利用memmove()函数删除模式串,得到剩余文本串。
- 重复以上两步操作,直至strstr()函数匹配不成功,即文本串中已无模式串。
经验总结
- char *strstr(const char *str1, const char *str2):接受两个参数 str1 和 str2,它们分别是要搜索的字符串和要查找的子字符串。函数会在 str1 中查找 str2 的第一次出现,并返回一个指向该位置的指针。如果未找到子字符串,则返回 NULL。
- void *memmove(void *dest, const void *src, size_t n):接受三个参数 dest、src 和 n,分别表示目标内存区域的起始地址、源内存区域的起始地址,以及要移动的字节数。
- 例子:
- 初始字符串为 “abcdefg”,要移除的子字符串是 “bcd”。
- 使用 strstr() 函数找到子字符串 “bcd” 在原始字符串中的位置。假设它的起始位置是指针 p。
- len 的值是子字符串 “bcd” 的长度,即 3。
- p + len 将指针移动到要移除的部分的结束位置之后的位置。假设 p 指向 “b”,那么 p + len 将指向 “e”。
- strlen(p + len) 计算从 “e” 开始的子字符串"efg"的长度,即 3。
- strlen(p + len) + 1 计算要移动的总字节数,即 4。
- memmove(p, p + len, strlen(p + len) + 1); 将从 “e” 开始的子字符串复制到 p 的位置,覆盖掉要移除的部分。这将得到新的字符串 “aefg”。
代码实现(C)
#include <stdio.h>
#include <string.h>
#define MaxSize 100000
char pat[MaxSize];
char txt[MaxSize];
void removeSubstring(char *str, const char *sub) {
int len = (int) strlen(sub);
// p记录第一次匹配成功时sub的位置
char *p = strstr(str, sub);
if (p) { // 匹配成功
while (p) {
// p指向要移除部分的起始位置
// p+len指向要移除部分之后的位置
// strlen(p+len)计算了从p+len开始的子字符串长度
// strlen(p+len)+1是要移动的字节数,加1是为了包括结尾空字符'\0'
memmove(p, p + len, strlen(p + len) + 1);
// 在移除后的字符串中继续匹配
p = strstr(str, sub);
}
printf("%s\n", str);
} else // 匹配失败
printf("-1\n");
}
int main() {
while (~scanf("%s %s", pat, txt))
removeSubstring(txt, pat);
return 0;
}