【发布时间】:2023-03-21 09:21:01
【问题描述】:
问题很简单:取一个字符串,然后只反转字母(小写或大写)的位置。将任何特殊字符留在原处。我的解决方案:
char * reverseOnlyLetters(char * S){
int Len = strlen(S);
char *StrBeg, *StrEnd, tempCh;
bool FoundStart = 0, FoundEnd = 0;
StrBeg = S;
StrEnd = S + (Len - 1);
for (int i = 0; i < (Len/2); i++)
{
if (((*StrBeg>= 'A') && (*StrBeg <= 'Z')) || ((*StrBeg >= 'a') && (*StrBeg <= 'z')))
{
FoundStart = 1;
}
else
{
StrBeg++;
}
if (((*StrEnd >= 'A') && (*StrEnd <= 'Z')) || ((*StrEnd >= 'a') && (*StrEnd <= 'z')))
{
FoundEnd = 1;
}
else
{
StrEnd--;
}
if(FoundStart && FoundEnd)
{
tempCh = *StrEnd;
*StrEnd = *StrBeg;
*StrBeg = tempCh;
StrBeg++;
StrEnd--;
FoundStart = 0;
FoundEnd = 0;
}
}
return S;
}
问题是像“a-bC-dEf-ghIj”这样的测试用例失败;中间的“E”和“f”要么根本不交换,要么(我怀疑)交换,然后交换回来。有人看到我做错了吗?
【问题讨论】:
-
这是您通常使用调试器逐行执行代码、检查变量值并最终在逻辑中找到错误的地方。跨度>
-
花絮:使用
<ctype.h>标头中的isalpha()宏;调用isalpha(*StrBeg)进行相同的测试,但更快更干净。 -
您的循环执行
Len/2次。在每次迭代中,它会根据情况增加/减少StrBeg或StrEnd或两者。虽然它在前面或后面找到了一个字母,并且正在递增/递减另一个指针以在其中找到一个字母,但在前面/后面没有取得任何进展。因此,可能需要更多的Len/2迭代才能完全通过一侧。您的循环需要不同的终止条件。 -
也许是
for (int i = 0; i < (Len/2); i++)-->while (StrBeg <= StrEnd)? (也许检测到没有进展) -
@chux - 恢复 Monica 使用了您对 while 循环的建议。完美运行。谢谢。
标签: c reverse c-strings letter function-definition