我一直在尝试创建一个从用户那里获取C样式字符串并回答回文的程序。我建立了一个函数(清除),该函数可以取出所有非小写字母(并将大写字母变成小写字母)。如果是回文,则另一个返回true或false。 purg函数可以按预期打印修改后的字符串(例如,“ Race 111 car”打印为“ racecar”),但是回文功能不能将修改后的字符串标记为回文,这是怎么回事?
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
bool isit(char *test, int u){
char *well = test;
bool chk = false;
for (int i = 0; i<2; i++) {
if (well[i] != well[u-i-1]) {
return false;
}
cout << well[i];
}
return true;
}
void purg(char *ini){
int x = 0;
bool answ;
char *elim = ini;
for (int i = 0; ini[i] != '\0'; i++) {
if (ini[i] >= 'A' && ini[i] <= 'Z') {
elim[i] = ini[i] + 32;
x++;
} else if (!(ini[i] >= 'a' && ini[i] <= 'z')) {
elim[i]='\0';
} else{
x++;
}
cout << elim[i]; //This reliably prints the answer I expect ("11race car_!" to "racecar")
}
answ = isit(&elim[0], x); //Is this passed correctly?
cout << endl;
if (answ == true){
cout << "It is a palindrome." << endl; //(user inputs like "RACecar", "racecar111", "racecar" and "WAAAAW111" are correct)
} else {
cout << "No palindrome here..." << endl; //("race car", "1racecar", and "d1o1d" are not, but they print as expected "racecar" and "dod")
}
}
int main(){
string str;//I'm not supposed to use C++ strings, should I replace this with char str[512]={}?
cout<<"Give me a string"<<endl;
getline(cin,str);
purg(&str[0]);
return 0;
}
[快速浏览了一下代码-似乎您将所有非字母字符替换为'\ 0',然后期望包含随机'\ 0'字符的字符串通过回文测试,该测试用于测试字符是否相等,将'\ 0'视为必须与另一面的镜像'\ 0'匹配的常规字符。
另外,您将包含'\ 0'字符的全长字符串传递给isit
函数,但仅给出未替换字符的数目作为长度。
您的字符串看起来正确打印的原因是,当您打印'\ 0'时,它什么都不做。用调试器查看ini
的内容,您会发现它真的被那些替换为'\ 0'的字符所取代。
尝试给它一个不包含任何非字母字符的字符串,如果我正确的话,它应该通过。
首先,将您的代码分成两个具有两个不同目的的不同函数,因此我们可以分别讨论它们:
void purge(char *ini) {
int x = 0;
bool answ;
char *elim = ini;
for (int i = 0; ini[i] != '\0'; i++) {
if (ini[i] >= 'A' && ini[i] <= 'Z') {
elim[i] = ini[i] + 32;
x++;
} else if (!(ini[i] >= 'a' && ini[i] <= 'z')) {
elim[i]='\0';
} else{
x++;
}
}
}
x
应该做什么?看起来它应该跟踪有效字符的数量,但是您永远不会使用它。实际上,如果我们运行测试:
char s[256] = "a!bc";
purge(s);
ASSERT_EQ("abc", s); // This fails, purge changed the string s into just "a".
好,使用x
!
void purge(char *str) {
int x = 0;
for (int i = 0; ini[i] != '\0'; i++) {
if (str[i] >= 'A' && str[i] <= 'Z') {
str[x] = str[i] - 'A' + 'a';
x++;
} else if (str[i] >= 'a' && str[i] <= 'z') {
str[x] = str[i];
x++;
}
}
// Make sure we null terminate the new string.
str[x] = '\0';
}
bool is_palindrome(char *test, int u){
char *well = test;
bool chk = false;
for (int i = 0; i<2; i++) {
if (well[i] != well[u-i-1]) {
return false;
}
cout << well[i];
}
return true;
}
u
应该是什么? well
应该是什么?i=0..2
循环播放?bool is_palindrome(char *str, int str_length) {
for (int i = 0; i < str_length / 2; i++) {
if (str[i] != str[str_length - i - 1]) {
return false;
}
}
return true;
}
通过将代码重写为两个单独的函数,我们可以开始对此代码添加测试。例如,我们可以使用Google的单元测试基础结构来做类似的事情:
TEST(MyTests, Purge_Nothing) {
char a[256] = "abc";
purge(a);
EXPECT_EQ(std::string("abc"), a);
}
TEST(MyTests, Purge_Non_Letters_At_Front) {
char a[256] = "!abc";
purge(a);
EXPECT_EQ(std::string("abc"), a);
}
TEST(MyTests, Purge_Non_Letter_In_Middle) {
char a[256] = "ab!c";
purge(a);
EXPECT_EQ(std::string("abc"), a);
}
TEST(MyTests, Purge_Non_Letters_At_End) {
char a[256] = "abc!";
purge(a);
EXPECT_EQ(std::string("abc"), a);
}
TEST(MyTests, Purge_Uppercase) {
char a[256] = "Abc!";
purge(a);
EXPECT_EQ(std::string("abc", a);
}
TEST(MyTests, Palindrome) {
EXPECT_TRUE(is_palindrome("abcba");
EXPECT_TRUE(is_palindrome("abba"));
EXPECT_TRUE(is_palindrome("aba"));
EXPECT_TRUE(is_palindrome("aa"));
EXPECT_TRUE(is_palindrome("z"));
EXPECT_TRUE(is_palindrome(""));
EXPECT_FALSE(is_palindrome("abcda");
EXPECT_FALSE(is_palindrome("abda");
EXPECT_FALSE(is_palindrome("abd");
EXPECT_FALSE(is_palindrome("ad");
}
C用于回文测试的不区分大小写功能的示例。您可以按原样使用C ++代码。
#include <string.h>
#include <ctype.h>
int is_palindrome(const char * str) {
const char * tail = str + strlen(str) - 1;
for ( ; str < tail && toupper(*str) == toupper(*tail); ++str, --tail )
;
return str >= tail;
}