【问题标题】:How to delete all characters from a string which are in another string?如何从一个字符串中删除另一个字符串中的所有字符?
【发布时间】:2025-12-23 17:05:07
【问题描述】:

我需要删除s1 中所有位于s2 中的字母。 我不明白我的代码有什么问题:

#include <stdio.h>
#include <stdlib.h>

void squeeze(char s1[], char s2[])
{
    int i,j;
    i=j=0;

    for(i; s2[i]!='\0'; i++) {
        for (j; s1[j] != '\0'; j++) {
            if (s1[j] == s2[i]) {
                s1[j] = s1[j + 1];
                --j;
            }
        }
    }
}

int main()
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    squeeze(w1,w2);
    puts(w1);
    return 0;
}

但输出是:

abcde

我应该修理什么?

【问题讨论】:

  • 您是否尝试过在调试器中逐句逐句执行代码?它告诉你什么?
  • 我是初学者,所以它什么也没告诉我,而且我以前从未使用过调试器
  • 那就把这当成是学习如何使用调试器的最佳时机吧。如果您想进行任何类型的编程,那么能够使用调试器确实是必不可少的。
  • 谢谢,我会看到的
  • 或者在你弄乱调试器之前尝试在你的算法中添加 printf 语句,这样你就可以得到一个显示算法如何进展的书面记录。这是调试程序的一种更通用的方法,因为调试器接口各不相同。

标签: c string c-strings


【解决方案1】:

对于初学者来说,变量 j 不会在每次外循环迭代的内循环中重置为 0

其次,如果一个字符必须被删除,那么它之后的所有字符都不会被移动到左边一个位置。您只是将删除的字符替换为字符串中的下一个字符。

该函数可以如下面的演示程序所示。

#include <stdio.h>
#include <string.h>

char * squeeze( char s1[], const char s2[] )
{
    for ( char *p = s1, *q = s1; *q; ++p )
    {
        if ( !*p || !strchr( s2, *p ) )
        {
            if ( q != p )
            {
                *q = *p;
            }
            if ( *p ) ++q;
        }
    }
    
    return s1;
}

int main( void )
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    
    puts( squeeze( w1, w2 ) );

    return 0;
} 

程序输出是

bcde

如果不允许使用标准的字符串函数和指针,那么程序可以如下所示。

#include <stdio.h>

char * squeeze( char s1[], const char s2[] )
{
    for ( size_t i = 0, j = 0; s1[j] != '\0'; ++i )
    {
        size_t k = 0;
        
        while ( s2[k] != '\0' && s2[k] != s1[i] ) ++k;
        
        if ( s2[k] == '\0' )
        {
            if ( j != i )
            {
                s1[j] = s1[i];
            }
            if ( s1[i] != '\0' ) ++j;
        }
    }
    
    return s1;
}

int main( void )
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    
    puts( squeeze( w1, w2 ) );

    return 0;
}

程序输出与之前的演示程序相同

bcde

【讨论】:

  • 谢谢,但我必须在没有指针/指标的情况下这样做
  • @HGH 指标是什么?
  • 我的意思是 ' * ' 只是不知道用英语怎么说,指针?索引?
【解决方案2】:

squeeze的两个问题:

  1. 您需要在每次通过循环时将 j 重新初始化为零。
  2. 您需要将字符串的整个剩余部分复制到左侧一个字符,而不仅仅是要删除的字符后面的字符。

我建议你将squeeze改写为:

void squeeze(char s1[], char s2[])
{
    int i,j;
    i=j=0;

    for( ; s2[i]!='\0'; i++) {
        for (j = 0; s1[j] != '\0'; j++) {
            if (s1[j] == s2[i]) {
              strcpy(s1+j, s1+j+1);
              --j;
            }
        }
    }
}

【讨论】:

  • 好的,谢谢,但是没有'strcpt'怎么办?
  • 编写另一个循环来执行strcpy 所做的事情。
  • 我尝试:void 挤压(char s1[],char s2[]){ int i,j,k; for( i= 0 ; s2[i]!='\0'; i++) { for (j = 0; s1[j] != '\0'; j++) { if (s1[j] == s2[ i]) { for(k=j; k != '\0'; k++) { s1[k] = s1[k+1]; } } } } }
  • @Bob Jarvis - 恢复 Monica 提供的带有 strcpy 的代码具有未定义的行为。
【解决方案3】:

我在这里看到一个问题,您的代码由于某种原因没有输入此语句:

 if (s1[j] == s2[i]) {
            s1[j] = s1[j + 1];
            --j;
        }

您的问题可能是为什么?因为 i 和 j 没有设置为 0 ,尝试打印它们,你会看到 j 将移动到 4 但 i 永远保持为 0 所以首先你可以通过这样做来修复它

for(i=0; s2[i]!='\0'; i++) {
for (j=0; s1[j] != '\0'; j++) {

然后您没有复制整个字符串并将其向后移动一步以重写找到的字符,您只移动了一个字符并将其留空 示例

input : abcde
output :b_cde

要解决此问题,您有两种方法: 使用strcpy 将代码后退一步

for(i=0; s2[i]!='\0'; i++) {
    for (j=0; s1[j] != '\0'; j++) {
        if (s1[j] == s2[i]){
            strcpy(s1+j, s1+j+1);
            --j;
        }


    }

或者您可以简单地使用 boucle 来创建相同的功能

for(i=0; s2[i]!='\0'; i++) {
    for (j=0; s1[j] != '\0'; j++) {
        if (s1[j] == s2[i]){
            for (k=j;s1[k] != '\0';k++)
            s1[k] = s1[k + 1];
            --j;
        }


    }

【讨论】:

  • 谢谢,但是没有'strcpy'怎么办?我知道我应该使用第三个循环,但我不知道如何......
  • @HGH 我不确定你是否看到最后一部分,尝试刷新页面,因为我已经写了如何使用 strcpy 使用 for boucle 的相同功能
  • 是的,页面没有刷新,现在我可以看到了,非常感谢!
  • @HGH 很高兴能帮到你。不要放弃并尝试使用更多示例来实现您的解决方案
  • @HGH 它在我身边有效,我尝试更改字符串。请提供更多信息以跟踪问题
【解决方案4】:
     #include <stdio.h>
     #include <string.h>

     int rem_str(char * porgstr, char * pdel) {
         if (!porgstr || !pdel) {
             return 0;
         }
         int i = 0;
         int j = 0;    
         char tmp[256] = {0};
         int len = strlen(pdel);
         for (i = 0; i < len; i++) {
            tmp[pdel[i]]++;
         }
         len = strlen(porgstr);
         for (i = 0, j=0; i < len; i++) {
            if(tmp[porgstr[i]] == 0) {
                porgstr[j] = porgstr[i];
                j++;
            }
         }
         porgstr[j] = 0;
         return 0;
     }
     int main () {
         char * input1 = strdup("origional string passed to program");
         char * input2 = strdup("sdel");

         printf("Input before del : %s\n", input1);
         rem_str(input1, input2);
         printf("String after del : %s\n", input1);

         return 0;
     }

输出:

      ./a.out 
     Input before del : origional string passed to program
     string after del : origiona tring pa to program

【讨论】:

    最近更新 更多