问题很简单:取一个字符串,然后反转唯一字母(小写或大写)的位置。将任何特殊字符保留在原处。我的解决方案:
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”或者根本不会被交换,或者(据我怀疑)会被交换,但随后会被交换回去。有人看到我在做什么错吗?
答案 0 :(得分:0)
使用此for循环的方法
for (int i = 0; i < (Len/2); i++)
不正确。假设字符串为"@AB"
。结果字符串看起来像"@BA"
但是使用循环,您将拥有(因为Len / 2
等于1
)
for (int i = 0; i < 1; i++)
在循环的第一次和单个迭代中,指针StrBeg
将递增
StrBeg++;
因为指向的字符不是字母。
所以没有什么可以逆转的。
可以通过以下方式更简单地编写函数
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * reverse_letters( char *s )
{
for ( char *first = s, *last = s + strlen( s ); first < last; ++first )
{
while ( first != last && !isalpha( ( unsigned char )*first ) ) ++first;
while ( last != first && !isalpha( ( unsigned char )*--last ) );
if ( first != last )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main( void )
{
char s[] = "one, two, three";
puts( s );
puts( reverse_letters( s ) );
char s1[] = "@AB";
puts( s1 );
puts( reverse_letters( s1 ) );
}
程序输出为
one, two, three
eer, hto, wteno
@AB
@BA
答案 1 :(得分:0)
(int i = 0; i <(Len / 2); i ++)的问题是这个。 如果字符串的长度是偶数,则可以,但是如果它不通过中间字符,则可以。在这种“ a-bC-dEf-ghIj”情况下,E,因此无法使用f进行切换。