小白教程

 找回密码
 立即注册
查看: 9945|回复: 5

[已解决]跪求大佬,字符串中删除一个特定字符

[复制链接]

1

主题

1

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2021-3-24 11:28:01 | 显示全部楼层 |阅读模式
  1. #include<stdio.h>
  2. #include<string.h>
  3. void na(char c[]);
  4. main()
  5. {
  6. char s[50]="my   name is wang yi han";
  7.     na(s);
  8. puts(s);
  9. }
  10. void na(char c[])
  11. {
  12. int b,p,k=0,v;
  13. v=strlen(c);
  14. char s,f;
  15. printf("请输入要删除的字符\n");
  16. scanf("%c",&s);
  17. for(b=0;c[b]!='\0';b++)
  18. {
  19. if(c[b]==s)
  20. {
  21.             k=k+1;
  22. for(p=b;c[p]==s;p++)
  23. {
  24. }
  25. f=c[b];
  26. c[b]=c[p];
  27. c[p]=f;
  28. }
  29. }
  30. c[v-k]='\0';
  31. }
复制代码
请问这个程序哪里不对?
最佳答案
2021-4-3 18:41:02
你这个算法的想法是把要删除的字符和后面第一个非删除字符交换

但是有两个问题
第一个, 你没有判断后面一串都是要删除的情况, 这个时候第一个非删除字符是字符串结尾'\0'
               你会把当前的要删除字符和字符串结尾交换了, 然后去判断下一个字符了, 这就导致循环无限向后推移,最后内存越界错误

第二个, 举例说明  mya 三个字符的字符串,假如要删除m
               第一次进来 发现m了k=1, 交换后,字符串是yma
              再次进入循环,有一次发现m, k=2,....
              再进来 k=3, .....
   所以你的k计数器是无效的

修改办法,
  1. for(b=0; c[b]!='\0'; b++)
  2.     {
  3.         if(c[b]==s)
  4.         {
  5.             // k = k + 1;
  6.             for(p=b;c[p]==s;p++)
  7.             {
  8.             }
  9.             f=c[b];
  10.             c[b]=c[p];
  11.             c[p]=f;
  12.             if ( c[b] == '\0') {
  13.                 k = p - b;
  14.                 break;
  15.             }
  16.         }
  17.     }  
复制代码
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-3-26 09:39:06 | 显示全部楼层
删除字符的话只需要找到字符后从后往前覆盖就可以了,你中间把字符交换,其实没有必要
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-4-3 18:41:02 | 显示全部楼层 &
你这个算法的想法是把要删除的字符和后面第一个非删除字符交换

但是有两个问题
第一个, 你没有判断后面一串都是要删除的情况, 这个时候第一个非删除字符是字符串结尾'\0'
               你会把当前的要删除字符和字符串结尾交换了, 然后去判断下一个字符了, 这就导致循环无限向后推移,最后内存越界错误

第二个, 举例说明  mya 三个字符的字符串,假如要删除m
               第一次进来 发现m了k=1, 交换后,字符串是yma
              再次进入循环,有一次发现m, k=2,....
              再进来 k=3, .....
   所以你的k计数器是无效的

修改办法,
  1. for(b=0; c[b]!='\0'; b++)
  2.     {
  3.         if(c[b]==s)
  4.         {
  5.             // k = k + 1;
  6.             for(p=b;c[p]==s;p++)
  7.             {
  8.             }
  9.             f=c[b];
  10.             c[b]=c[p];
  11.             c[p]=f;
  12.             if ( c[b] == '\0') {
  13.                 k = p - b;
  14.                 break;
  15.             }
  16.         }
  17.     }  
复制代码
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-4-14 01:56:14 | 显示全部楼层
注释掉一行语句
/*   */  是注释掉一大段语句
// 注释掉一行语句
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-4-19 17:20:07 | 显示全部楼层
好好看看代码好不。
看了半天理解你的代码,理解你的思路,沿着你的思路把解决问题了, 然后你还要把自己带沟里去

注释掉k=k+1, 是因为按照你的思路这样计数是无效的,理由前面已经给你解释了

补充上去的那三行代码, 解决了一个问题,就是当你已经把字符串互换到最后的若干个都是要删除的数据的时候,可互换的非要删除字符是字符串的结尾, 而p就是字符串结尾的序号, 所以p-b就是一共有一个要删除的字符串

直接计算得到了结果, 还循环计数个鬼啊

此外,倒数第二行的那个 c[v-k] = '\0' 那一行在这个修正的代码下也是多余的
因为字符串结尾已经被互换过去了。
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-4-29 10:15:07 | 显示全部楼层
复杂化了
定义SRC[]记录处理前的字符串
定义DST[]记录处理后的字符串
然后将不等于要删除的字符,依次copy到dst字符数组里就可以了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-11-24 13:47 , Processed in 0.024309 second(s), 28 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表