问题
通过我在网上找到的一些编程面试挑战,我不得不编写一个算法来反转 const char * 并返回一个指向新 char * 的指针。我想我有它,但为了让它正常工作,我不得不做一些奇怪的事情——基本上必须自己考虑空终止字符。不知何故,我觉得这是错误的,但我很难过,我想知道是否有人可以帮助我:
char * reverse(const char * str)
{
int length = strlen(str);
char * reversed_string = new char[length+1];
for(int i = 0; i < length; ++i)
{
reversed_string[i] = str[(length-1) - i];
}
//need to null terminate the string
reversed_string[length] = '\0';
return reversed_string;
}
int main(int argc, char * argv[])
{
char * rev_str = reverse("Testing");
cout << "Your string reversed is this: " << rev_str << endl;
delete rev_str;
rev_str = 0;
return 0;
}
解决方案
-
上面的 for 循环有错字。检查循环变量 i 应该是 <= 而不是 <,否则对于奇数个元素将失败。for(int i = 0; i <= 长度/2; ++i)
-
char * reverse(const char * str) { if (!str) return NULL; int length = strlen(str); char * reversed_string = new char[length+1]; for(int i = 0; i < length/2; ++i) { reversed_string[i] = str[(length-1) - i]; reversed_string[(length-1) - i] = str[i]; } //need to null terminate the string reversed_string[length] = '\0'; return reversed_string; }
一半的时间,但复杂性相同(注意可能会因一个错误而关闭)
如果传递了一个空指针,那么到目前为止提交的所有
strlen()
答案都将失败——它们中的大多数会跳转到立即调用一个可能的空指针——这可能会导致你的进程出现段错误。许多答案都对性能着迷,以至于他们错过了问题的关键问题之一: reverse a
const char *
,即您需要制作反向副本,而不是就地反向。如果需要副本,您会发现很难将迭代次数减半!不需要临时变量的方法
int length = strlen(string); for(int i = 0; i < length/2; i++) { string[i] ^= string[length - i] ^= string[i] ^= string[length - i]; }
字符串反转到位,没有临时变量。
static inline void byteswap (char *a, char *b) { *a = *a^*b; *b = *a^*b; *a = *a^*b; } void reverse (char *string) { char *end = string + strlen(string) - 1; while (string < end) { byteswap(string++, end--); } }
它不会更有效,但是您可以通过将每个字母推入堆栈,然后将它们弹出到新分配的缓冲区中来展示数据结构的知识。
这将需要两次通过和一个临时堆栈,但我可能会更相信自己第一次就能做到这一点,然后不会像上面那样犯一个错误。
char* stringReverse(const char* sInput) { std::size_t nLen = strlen(sInput); std::stack<char> charStack; for(std::size_t i = 0; i < nLen; ++i) { charStack.push(sInput[i]); } char * result = new char[nLen + 1]; std::size_t counter = 0; while (!charStack.empty()) { result[counter++] = charStack.top(); charStack.pop(); } result[counter] = '\0'; return result; }