我正在使用递归编写回文检查器。我很困惑为什么要删除
return true
函数末尾的语句会影响返回值。
int firstChar = 0;
int lastChar = 0;
// These two variables are used to transverse the string from both ends
// eventually meeting
代码1:
bool palindromeCheck (string text, int firstChar, int lastChar)
{
string tempCleanText = text;
// Removes all punctation and space
if (firstChar == 0)
{
// Cleans text, ignore.
tempCleanText = cleanString(tempCleanText);
// Sets this variable to the end of the string
lastChar = tempCleanText.size() - 1;
}
// Base Case
if (firstChar >= lastChar)
{
return true;
}
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
return true; // Keeping this in works
}
对于所有回文应返回true,对所有非回文应返回false。
代码2:
bool palindromeCheck (string text, int firstChar, int lastChar)
{
string tempCleanText = text;
// Removes all punctation and space.
if (firstChar == 0)
{
// Cleans text, ignore.
tempCleanText = cleanString(tempCleanText);
// Sets this variable to the end of the string
lastChar = tempCleanText.size() - 1;
}
// Base Case
if (firstChar >= lastChar)
{
return true;
}
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
// there is no return true here, and so the output is no longer correct
}
仅对于某些回文,返回true,而对于所有非回文,则返回false。
回文,例如,
amanaplanacanalpanama
返回false,应返回true。
通过测试,表明使用最后一个回文输入基本案例,这意味着函数将其视为有效回文。但是,我假设程序随后展开了调用堆栈,并在处理所有先前的函数调用时,使该函数返回false。
可能是
// ...
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
return palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
return false;
// ...
对于初学者,该功能在任何情况下均不正确。例如,对于字符串"1231"
,该函数返回true
。希望您可以自己检查。
这部分功能
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
return true; // Keeping this in works
至少应替换以下代码段
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
return palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
这是该返回语句
return true; // Keeping this in works
应完全删除。
关于您的问题,然后没有最后一个return语句,该函数具有未定义的行为,因为它在if语句之后不返回任何内容。那是if语句
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
成功执行,前提是
tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
并且在执行if语句的子语句后,函数返回什么?没有! :)
此外,声明除字符串本身之外的两个其他参数(索引)也没有意义,因为在任何情况下,字符串都是通过值传递的,并且始终可以通过调用成员函数size()
来获取其大小。
我可以建议以下函数的实现,与您的函数相似,如果传递了空字符串,则该函数实现将返回true。
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
bool palindromeCheck( std::string s )
{
if ( s.size() < 2 )
{
return true;
}
else if ( ispunct( ( unsigned char )s.front() ) || isspace( ( unsigned char )s.front() ) )
{
return palindromeCheck( s.substr( 1 ) );
}
else if ( ispunct( ( unsigned char )s.back() ) || isspace( ( unsigned char )s.back() ) )
{
return palindromeCheck( s.substr( 0, s.size() - 1 ) );
}
else if ( s.front() == s.back() )
{
return s.size() == 2 ? true : palindromeCheck( s.substr( 1, s.size() - 2) );
}
else
{
return false;
}
}
int main()
{
std::cout << std::boolalpha << palindromeCheck( "" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1 1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1,2,2,1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1 2 3 2 1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "12341" ) << '\n';
return 0;
}
程序输出为
true
true
true
true
true
false
从非空函数返回而未通过return
关键字显式返回值的情况将调用未定义行为。根据C ++规范,调用未定义行为的程序实际上可以自由地做任何事情,而导致任何怪异的一切责任都将落在编写调用未定义行为代码的程序员的脚上。
在这种情况下实际上可能发生的情况是,当您的函数通过删除函数的末尾而返回(并且不执行return false
时),该函数的返回值的存储位置根本就不会写入-这意味着,就调用代码而言,函数返回的值将等于函数返回时在该位置出现的任何值。该位置处的现有值将是任意的且难以预测,因为它是有关程序执行方式的各种细节的结果,因此,程序的行为也将是任意的且难以预测的。
解决方案是确保始终显式返回值;在编译器中启用警告将通过警告您是否忘记在某些代码路径中返回值来帮助您完成该任务。