繁体   English   中英

检查 C++ 上的反转文本(不适用于 -1 索引?)

[英]Checking reversed text on C++ (doesn't work with a -1 index?)

我正在制作一个简单的回文检查器,无法理解为什么迭代器使用索引 0,但不能使用索引 -1,您可以看到两个代码打印相同的文本,但不是相同的 boolean。

谁能解释一下这背后的逻辑是什么?

两个代码唯一不同的部分是:

for(int i=text.size();i>= -1 ;i--)
for(int i=text.size() -1 ;i>= 0 ;i--)

在职的:


#include <iostream>

// Define is_palindrome() here:
std::string is_palindrome(std::string text){
  std::string reverse= "";
  for(int i=text.size()-1;i>=0;i--){
    reverse += text[i];
  }
  if(reverse == text){

    return text + " IS palindrome (reverse text: " + reverse +")";
  } else {

    return text + " NOT palindrome (reverse text: " + reverse + ")";
  }
}

int main() {
  
  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";
  
}

output

madam IS palindrome (reverse text: madam)
ada IS palindrome (reverse text: ada)
lovelace NOT palindrome (reverse text: ecalevol)

不工作

#include <iostream>

// Define is_palindrome() here:
std::string is_palindrome(std::string text){
  std::string reverse= "";
  for(int i=text.size();i>=-1;i--){
    reverse += text[i];
  }
  if(reverse == text){

    return text + " IS palindrome (reverse text: " + reverse +")";
  } else {

    return text + " NOT palindrome (reverse text: " + reverse + ")";
  }
}

int main() {

  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";

}

output

madam NOT palindrome (reverse text: madam)
ada NOT palindrome (reverse text: ada)
lovelace NOT palindrome (reverse text: ecalevol)

C++ 使用基于 0 的索引,即N大小容器的有效索引是0,1,2...N-1 如果您尝试使用超出范围的索引,您的代码会调用未定义的行为。

看这段代码的output:

#include <iostream>
#include <string>

void foo(const std::string& text){
    for(int i=text.size();i>=-1;i--){
        std::cout << i << "\n";
    }
}
int main() {
    foo("madam");
}

这是

5
4
3
2
1
0
-1

-15都不是字符串的元素,因为它只有5字符。 (对于5 ,我允许自己稍微简化一下问题,因为字符串在访问最后一个字符 null 终止符时有一些奇怪的地方。因为-1肯定是越界并且使用std::string你通常不需要处理null 终止符明确,这对于这个答案是可以的)。

现在看这段代码的output:

#include <iostream>
#include <string>

void foo(const std::string& text){
    for(int i=text.size()-1;i>=0;i--){
        std::cout << i << "\n";
    }
}
int main() {
    foo("madam");
}

这是

4
3
2
1
0

它迭代输入字符串的所有字符。 这就是为什么这是正确的,而另一个是错误的。

当您的代码具有未定义的行为时,任何事情都可能发生。 结果可能看起来正确或部分正确。 错误的代码不一定会产生明显错误的 output。

请注意,当字符串的大小为0时, for(int i=text.size()-1;i>=0;i--)会出现问题,因为size()返回一个 unsigned ,它会环绕导致 a大正数。 您可以通过使用迭代器来避免这种情况。 有一些反向迭代器使反向循环看起来与正向循环相同:

#include <iostream>
#include <string>

int main() {    
    std::string text("123");
    for (auto i = text.rbegin(); i != text.rend(); ++i) std::cout << *i;
}

Output

321

除了 463035818_is_not_a_number 的答案之外,您还可以使用迭代器从另一个字符串构造一个字符串:

#include <iostream>
#include <string>

int main() {    
    std::string text("123");
    std::string rev(crbegin(text), crend(text));
    std::cout << rev << '\n';
}

还有std::reverse

#include <iostream>
#include <string>
#include <algorithm>

int main() {    
    std::string text("123");
    reverse(begin(text), end(text));
    std::cout << text << '\n';
}

但是对于回文,您不必比较两个完整的字符串。 你只需要看到字符串的前半部分等于字符串后半部分的反转。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM