C语言递归merge2函数无法返回至断言处求助
C语言拉链式字符串合并递归函数无法返回至断言环节排查
我正在编写一个将两个字符串按“拉链式”合并的C语言代码,示例如下:
s1 = "1 3 5 7",s2 = "2 4 6",预期返回结果为"1 2 3 4 5 6 7"。
我实现了递归函数merge2,但该函数执行后无法返回至断言校验的位置,既没有断言失败的提示,完全无法到达断言环节。我仅学习C语言3个月,已尝试了所有能想到的方法仍无法解决,从逻辑上看函数应该能返回正确字符串,恳请帮忙排查问题。
实现代码如下:
char* merge2(char* s1, int wwa1, char*s2, int wwa2, char*ans){ //printf("commence next recursion\n"); char currentWord1[45]; char currentWord2[45];//longest word in english has 45 letters currentWord1[0]='\0'; currentWord2[0]='\0'; //printf("after current word\n"); for(int n=wwa1; s1[n]!=' ' && n<strlen(s1); n++){ char addition[] = {s1[n],'\0'}; strcat(currentWord1,addition); wwa1=n; } //printf("%s\n",currentWord1); wwa1+=1; for(int w=wwa2; s2[w]!=' ' && w<strlen(s2); w++){ char add[] = {s2[w],'\0'}; strcat(currentWord2,add); wwa2=w; } //printf("%s\n",currentWord2); wwa2+=1; if(strlen(currentWord1)>0 && strlen(currentWord1)>0){ wwa1+=1; wwa2+=1; strcat(currentWord1," "); strcat(currentWord2," "); } else if(strlen(currentWord1)>0 && strlen(currentWord1)==0 && wwa1<strlen(s1)){ wwa1+=1; strcat(currentWord1," "); } else if(strlen(currentWord1)==0 && strlen(currentWord1)>0 && wwa2<strlen(s2)){ wwa2+=1; strcat(currentWord2," "); } strcat(ans,strcat(currentWord1,currentWord2)); int anslen = strlen(ans); int straddlen = strlen(s1)+strlen(s2); /* printf("len ans: %d\n", anslen); printf("tot len: %d\n", straddlen); printf("ans: %s\n", ans); printf("%s, %d, %s, %d, %s\n",s1,wwa1,s2,wwa2,ans);*/ if(strlen(s1)+strlen(s2)==anslen-3){ if(anslen>=2) ans[anslen-2]='\0'; //printf("\nYOU ARE RETURNING: %s.\n",ans); return ans; } return merge2(s1,wwa1,s2,wwa2,ans); }
问题排查与修正要点
1. 逻辑矛盾的条件判断
代码中多个条件分支存在致命逻辑错误:
- 第一个if条件重复判断
strlen(currentWord1)>0,正确逻辑应为同时判断currentWord1和currentWord2均不为空:strlen(currentWord1)>0 && strlen(currentWord2)>0 - 后续两个else if条件包含
strlen(currentWord1)>0 && strlen(currentWord1)==0这种完全矛盾的判断,导致这些分支永远无法执行,无法处理“一个字符串已处理完、另一个还有剩余字符”的场景。
2. 错误的递归终止条件
终止条件strlen(s1)+strlen(s2)==anslen-3无合理依据,原字符串总长度与合并后字符串长度的关系并非固定减3,这会导致终止条件永远无法满足,递归无限调用最终造成栈溢出,程序根本走不到断言校验环节。
正确的终止条件应为两个字符串的索引都到达末尾时停止递归:
if (wwa1 >= strlen(s1) && wwa2 >= strlen(s2)) { // 移除最后多余的空格 if (anslen > 0) ans[anslen - 1] = '\0'; return ans; }
3. 索引处理越界问题
获取完当前单词后直接执行wwa1+=1,会导致当单词位于字符串末尾时,wwa1超出字符串长度,后续的wwa1+=1会进一步加剧越界,引发未定义行为。
正确的索引更新应跳过当前单词后的所有空格,直接定位到下一个单词的起始位置:
// 处理s1的索引更新 int n = wwa1; while (n < strlen(s1) && s1[n] != ' ') { currentWord1[n - wwa1] = s1[n]; n++; } currentWord1[n - wwa1] = '\0'; // 跳过空格,定位到下一个单词起始 wwa1 = n; while (wwa1 < strlen(s1) && s1[wwa1] == ' ') wwa1++;
4. 字符串拼接的冗余与风险
用strcat(currentWord1,addition)逐个字符拼接效率极低,且strcat(ans,strcat(currentWord1,currentWord2))会修改栈上的currentWord1数组,逻辑混乱且存在数组溢出风险(若单词长度接近45)。建议直接通过索引赋值构建currentWord,再分别拼接到ans中。
修正后的示例代码片段
char* merge2(char* s1, int wwa1, char* s2, int wwa2, char* ans) { char currentWord1[45] = {0}; char currentWord2[45] = {0}; // 获取s1当前单词并更新索引 int n = wwa1; while (n < strlen(s1) && s1[n] != ' ') { currentWord1[n - wwa1] = s1[n]; n++; } wwa1 = n; while (wwa1 < strlen(s1) && s1[wwa1] == ' ') wwa1++; // 获取s2当前单词并更新索引 int w = wwa2; while (w < strlen(s2) && s2[w] != ' ') { currentWord2[w - wwa2] = s2[w]; w++; } wwa2 = w; while (wwa2 < strlen(s2) && s2[wwa2] == ' ') wwa2++; // 拼接当前单词到ans if (strlen(currentWord1) > 0) { strcat(ans, currentWord1); strcat(ans, " "); } if (strlen(currentWord2) > 0) { strcat(ans, currentWord2); strcat(ans, " "); } int anslen = strlen(ans); // 递归终止条件:两个字符串都处理完毕 if (wwa1 >= strlen(s1) && wwa2 >= strlen(s2)) { if (anslen > 0) ans[anslen - 1] = '\0'; // 移除最后空格 return ans; } return merge2(s1, wwa1, s2, wwa2, ans); }
内容的提问来源于stack exchange,提问作者Caprisun73
相关产品推荐
相关产品推荐

