判断两字符串是否为变位词的代码逻辑问题:赋值'0'的错误排查
变位词判断代码的逻辑错误分析
你的代码核心问题出在标记已匹配字符的方式和内层循环的逻辑上,下面具体分析str1[j]='0';的错误及原因:
1. str1[j]='0';直接导致的逻辑错误
(1)重复消耗匹配项
你原本的思路是标记已匹配字符避免重复使用,但内层循环找到匹配后没有立即退出,而是继续遍历整个str1。这会导致:当str1中有多个和当前str2[i]相同的字符时,所有这些字符都会被改成'0',直接消耗掉原本应该留给str2后续相同字符的匹配项。
比如输入str1="aa",str2="aa":
- 外层循环
i=0(处理str2的第一个'a'),内层循环遍历j=0和j=1:j=0匹配,k++,str1[0]被改成'0';- 继续
j=1,str1[1]还是'a',再次匹配,k++,str1[1]也被改成'0';
- 外层循环
i=1(处理str2的第二个'a'),此时str1全是'0',找不到匹配,k=0,错误输出NO。
(2)原字符与标记冲突
如果输入的字符串本身包含'0'这个字符,标记操作会把原有的'0'和已匹配的标记混淆。比如输入str1="0a",str2="00":
- 外层
i=0处理第一个'0',找到str1[0]的原'0',改成'0'(等于没改); - 外层
i=1处理第二个'0',找到str1[0]的'0',但这其实是原字符,不是已标记的位置,最终错误输出YES,但实际两个字符串不是变位词。
2. 为何移除该行后部分输入能正常运行
移除str1[j]='0';后,代码会对每个str2[i]遍历str1所有字符,只要找到至少一个匹配就计数k++。这种逻辑在字符串中没有重复字符时是有效的,比如str1="abc"和str2="cba",每个字符只会匹配一次,最终能正确输出YES。
但只要存在重复字符,这种逻辑就会失效:比如str1="aab"和str2="abb",代码会错误输出YES,因为每个str2的字符都能在str1中找到匹配,但实际字符数量不对应。
修复建议
正确的标记思路应该是找到第一个匹配的字符后,立即标记并退出内层循环,避免重复消耗:
#include<stdio.h> #include<string.h> int main() { char str1[100]; char str2[100]; scanf("%s %s", str1, str2); int a=strlen(str1); int b=strlen(str2); if(a!=b){printf("NO");return 0;} for(int i=0;i<b;i++){ int found = 0; for(int j=0;j<a;j++){ if(str2[i]==str1[j]){ found = 1; str1[j] = '\0'; // 用字符串结束符标记,避免和原字符冲突 break; // 找到匹配后立即退出内层循环 } } if(!found){printf("NO");return 0;} } printf("YES"); }
或者更高效的方式是用数组统计每个字符的出现次数,对比两个数组是否一致。
内容的提问来源于stack exchange,提问作者JAISHREEDEVAKI T
相关产品推荐
相关产品推荐

