2017年兰州大学研究生复试机试题:字符串匹配

本文介绍如何使用C语言中的strstr函数定位子串,结合memmove函数删除子串,解决在给定文本串中移除模式串的问题。提供了解题思路和实际代码示例。
摘要由CSDN通过智能技术生成

Problem Description

输入两个字符串,分别为模式串和文本串。若模式串是文本串的子字符串,则要求将文本串中的子字符串删除,并返回删除子字符串后的字符串。

Input

首先输入模式串,然后输入文本串。(均由大写或者小写字母构成,二者以空格为间隔隔开)

Output

若模式串是文本串的子字符串,输出删除子字符串后的字符串。
若模式串不是文本串的子字符串,输出-1。

Sample Input

dfg asdfghj

Sample Output

ashj

解题思路

  1. 利用strstr()函数得到模式串在文本串中的起始位置。
  2. 利用memmove()函数删除模式串,得到剩余文本串。
  3. 重复以上两步操作,直至strstr()函数匹配不成功,即文本串中已无模式串。

经验总结

  1. char *strstr(const char *str1, const char *str2):接受两个参数 str1 和 str2,它们分别是要搜索的字符串和要查找的子字符串。函数会在 str1 中查找 str2 的第一次出现,并返回一个指向该位置的指针。如果未找到子字符串,则返回 NULL。
  2. void *memmove(void *dest, const void *src, size_t n):接受三个参数 dest、src 和 n,分别表示目标内存区域的起始地址、源内存区域的起始地址,以及要移动的字节数。
  3. 例子:
    1. 初始字符串为 “abcdefg”,要移除的子字符串是 “bcd”。
    2. 使用 strstr() 函数找到子字符串 “bcd” 在原始字符串中的位置。假设它的起始位置是指针 p。
    3. len 的值是子字符串 “bcd” 的长度,即 3。
    4. p + len 将指针移动到要移除的部分的结束位置之后的位置。假设 p 指向 “b”,那么 p + len 将指向 “e”。
    5. strlen(p + len) 计算从 “e” 开始的子字符串"efg"的长度,即 3。
    6. strlen(p + len) + 1 计算要移动的总字节数,即 4。
    7. 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;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值