我在我的代码中找不到任何几乎回文的错误。该声明
'r = isPalindrome(str, p[0], p[1]-1);'
没有被执行,而函数调用p&q被执行得很好。它只输出p &有人能解释一下这个程序的流程出了什么问题吗?
#include <iostream>
#include<vector>
using namespace std;
int arr[2];
int* isPalindrome(string &s, int i, int j){
int sz = s.length();
if(i==j) return NULL;
while(i<j){
if(s[i] == s[j]){
i++;
j--;
}
else{
arr[0] = i;
arr[1] = j;
return arr;
}
}
return NULL;
}
int main()
{
string s = "abcdefdba", str;
int *p, *q, *r;
// removes any additional character or spaces and make lower-case
for(int i=0; i<s.length();i++){
if(s[i] >= 65 && s[i]<=90) str.push_back(s[i]+32);
if((s[i] >=97 && s[i]<=122) || (s[i]>=48 && s[i]<=57)) str.push_back(s[i]);
}
p = isPalindrome(str, 0, str.length()-1);
cout<<"pointer p: "<<p[0]<<p[1]<<endl;
if(p==NULL) cout<<"true";
else{
q = isPalindrome(str, p[0]+1, p[1]);
r = isPalindrome(str, p[0], p[1]-1); // not getting executed
}
cout<<"pointer q: "<<q[0]<<q[1]<<endl;
cout<<"pointer r: "<<r[0]<<r[1]<<endl;
if(q==NULL || r==NULL) cout<<"true";
else cout<<"false";
return 0;
}
让我们假设你是对的,函数没有被执行,让我们找出为什么编译器可能会以这样一种不需要函数调用的方式优化它:
int* isPalindrome(string &s, int i, int j)
返回指向全局数组arr
或NULL的指针,并且除了写入arr之外没有副作用。
让我们分析一下main函数:
p = isPalindrome(str, 0, str.length()-1);
cout<<"pointer p: "<<p[0]<<p[1]<<endl;
if(p==NULL) cout<<"true";
else {
你解引用p
,所以p
不能为NULL,编译器总是可以取else分支。
q = isPalindrome(str, p[0]+1, p[1]);
r = isPalindrome(str, p[0], p[1]-1); // not getting executed
}
cout<<"pointer q: "<<q[0]<<q[1]<<endl;
cout<<"pointer r: "<<r[0]<<r[1]<<endl;
if(q==NULL || r==NULL) cout<<"true";
else cout<<"false";
再次取消对q
和r
的引用,使它们不能为NULL。所以isPalindrom在两种情况下都必须返回arr
的地址,并且必须写arr[0]
和arr[1]
,即p
,q
和r
。第二个isPalindrom
调用改变了p[0]
和p[1]
,这改变了第三个isPalindrom
调用所做的。我认为没有一个可以跳过。
但是编译器可以在编译时计算出所有的错误,并消除所有错误。
在输出中,您应该看到最后两个cout
调用输出相同的内容。这可能会让您认为跳过了其中一个函数调用。但是你看到的是它们都只是打印相同的全局arr
。
你应该做的是返回std::optional<std::pair<int, int>>
而不是全局数组。
更好:int
不是索引的正确类型,应该是std::size_t
。所以std::optional<std::pair<std::size_t, std::size_t>>
为什么不返回子字符串的迭代器呢?让它成为const,参数应该是const std::string &
:std::optional<std::pair<std::string::const_iterator, std::string::const_iterator>>
或者让我们变得更现代,返回一个字符串视图:std::optional<std::string_view>