简体   繁体   English

搜索和删除字符串中的子字符串

[英]Search and delete substrings from a string

I want to remove all instances of a string(smaller or equal) than another string. 我想删除一个字符串的所有实例(小于或等于)。 Even overlapping substrings should be completely removed. 即使重叠的子字符串也应完全删除。 This is the code I have written: 这是我编写的代码:

#include<stdio.h>

int Checknremove(char *str,char *ph)
{
        while( *str )
        {
                char *k=ph,*s=str;
                while( *k && *k==*s ) ++k,++s;
                if( !*k )
                {
                        while( *s ) *str++=*s++;
                        *str=0;
                        return 1;
                }
                ++str;
        }
        return 0;
}

int main()
{
        int t;
        scanf("%d", &t);
        while(t--)
        {
                char str[100], ph[100];
                scanf("%s %s", str, ph);
                while(Checknremove(str,ph));
                puts(str);
        }
        return 0;
}

The problem is it only removes the substrings which are distinct and not overlapping ones. 问题在于它仅删除了不同且不重叠的子字符串。 Example: catafjkgjcat cat will output afjkgj but aababbaababbac aababba will output ababbac and not c as I want it to. 示例:catafjkgjcat cat将输出afjkgj但aababbaababbac aababba将输出ababbac而不是c,如我所愿。 What should I do? 我该怎么办?

aababbaababbac has two aababba , but they are overlapped. aababbaababbac有两个aababba ,但是它们是重叠的。

You should mark where to delete first, and then remove marked characters instead of deleting what you found immediately. 您应该先标记要删除的位置,然后再删除标记的字符,而不是立即删除找到的字符。

UPDATE: here is a sample implementation. 更新:这是一个示例实现。

#include<stdio.h>
#include<stdlib.h> /* for using malloc */
#include<string.h> /* for using strlen and strncmp */

/* add const since it won't be modified */
/* made the return value void since this will remove all target by one call */
void Checknremove(char *str,const char *ph)
{
        size_t srclen = strlen(str);
        size_t targetlen = strlen(ph);
        char *delete_flag = calloc(srclen, 1);
        size_t i, j;
        if(delete_flag == NULL) exit(1); /* failed to allocate the memory */
        /* search the target and mark it */
        for(i = 0; i <= srclen - targetlen; i++)
        {
                if(strncmp(str + i, ph, targetlen) == 0)
                {
                    for (j = 0; j < targetlen; j++) delete_flag[i + j] = 1;
                }
        }
        /* copy undeleted characters to str */
        for (i = j = 0; i < srclen; i++)
        {
                if (!delete_flag[i]) str[j++] = str[i];
        }
        str[j] = '\0';
        free(delete_flag);
}

int main()
{
        int t;
        scanf("%d", &t);
        while(t--)
        {
                char str[100], ph[100];
                scanf("%s %s", str, ph);
                Checknremove(str,ph);
                puts(str);
        }
        return 0;
}

The problem of course is the "nremove". 问题当然是“ nremove”。 If you do the remove AS you scan (ie immediately), the overlapping part will no longer be in the str to match on the next iteration/call. 如果您执行删除AS扫描(即立即),则重叠部分将不再位于str中以在下一次迭代/调用时匹配。

What you should do is separate the checking from the removing: do all the checking before doing ANY removing. 您应该做的是将检查与删除分开:在进行任何删除之前都要进行所有检查。 You'll have to store string indexes or something to communicate between the two. 您必须存储字符串索引或两者之间的通讯对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM