简体   繁体   English

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

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

I was making a simple palindrome checker and can't understand why the iterator works with index 0, but won't work with index -1, you can see that both codes print the SAME text, but not the same boolean.我正在制作一个简单的回文检查器,无法理解为什么迭代器使用索引 0,但不能使用索引 -1,您可以看到两个代码打印相同的文本,但不是相同的 boolean。

Can anyone explain me what's the logic behind this?谁能解释一下这背后的逻辑是什么?

The only different part on both codes is this:两个代码唯一不同的部分是:

for(int i=text.size();i>= -1 ;i--) Not Working for(int i=text.size();i>= -1 ;i--)不工作
for(int i=text.size() -1 ;i>= 0 ;i--) Working for(int i=text.size() -1 ;i>= 0 ;i--)工作

WORKING:在职的:


#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 output

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

NOT WORKING不工作

#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 output

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

C++ uses 0-based indexing, ie valid indices of a N sized container are 0,1,2...N-1 . C++ 使用基于 0 的索引,即N大小容器的有效索引是0,1,2...N-1 If you try to use an index out of bounds your code invokes undefined behavior.如果您尝试使用超出范围的索引,您的代码会调用未定义的行为。

Look at the output of this code:看这段代码的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");
}

It is这是

5
4
3
2
1
0
-1

Both -1 and 5 are not elements of the string, because it has only 5 characters. -15都不是字符串的元素,因为它只有5字符。 (For 5 I am allowing myself to simplify the matter a bit, because strings have some oddities for accessing the one past last character null terminator. As -1 definitely is out of bounds and with std::string you usually need not deal with the null terminator explicitly, this is ok for this answer). (对于5 ,我允许自己稍微简化一下问题,因为字符串在访问最后一个字符 null 终止符时有一些奇怪的地方。因为-1肯定是越界并且使用std::string你通常不需要处理null 终止符明确,这对于这个答案是可以的)。

Now look at the output of this code:现在看这段代码的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");
}

It is这是

4
3
2
1
0

It iterates all characters of the input string.它迭代输入字符串的所有字符。 Thats why this is correct and the other is wrong.这就是为什么这是正确的,而另一个是错误的。

When your code has undefined behavior anything can happen.当您的代码具有未定义的行为时,任何事情都可能发生。 The results may appear to be correct or partially correct.结果可能看起来正确或部分正确。 Wrong code does not necessarily produce obviously wrong output.错误的代码不一定会产生明显错误的 output。

Note that for(int i=text.size()-1;i>=0;i--) is a problem when the size of the string is 0 , because size() returns an unsigned which wraps around to result in a large positive number.请注意,当字符串的大小为0时, for(int i=text.size()-1;i>=0;i--)会出现问题,因为size()返回一个 unsigned ,它会环绕导致 a大正数。 You can avoid that by using iterators instead.您可以通过使用迭代器来避免这种情况。 There are reverse iterators that make a reverse loop look the same as a forward loop:有一些反向迭代器使反向循环看起来与正向循环相同:

#include <iostream>
#include <string>

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

Output Output

321

In addition to the answer by 463035818_is_not_a_number, you can also construct a string from another string using iterators:除了 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';
}

And there's std::reverse还有std::reverse

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

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

But for a palindrome, you don't have to compare two whole strings.但是对于回文,您不必比较两个完整的字符串。 You just need to see of the first half of the string is equal to the reverse of the last half of the string.你只需要看到字符串的前半部分等于字符串后半部分的反转。

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

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