在 if 语句中进行比较时 strrev 不起作用
strrev not working when comparing in an if statement
PD:我被迫学习“strrev()”,因为这是我学士学位的一部分,请不要考虑推荐我“reverse()”。
int n = 0, str, revc=0;
char a[256], v[101][21], *p, sep[]=" :;.,", rev[256];
cin.get(a, 256);
p = strtok(a, sep);
while(p){
strcpy(v[n++], p);
p = strtok(NULL, sep);
}
for(int i = 0; i < n; i++){
str = strlen(v[i]);
if(stricmp(strrev(v[i]), v[i]) == 0 && str > revc){
strcpy(rev, v[i]);
revc = str;
}
}
cout << rev;
代码解释&遇到的问题
**这段代码的目的是找到数组(a)中最长的回文词
代码的第一部分标记了整个“a”数组,分隔符为“sep”。
第二部分代码在v中查找是否有回文词;例如,如果 a 是:
121 hellO WorlD; this Isi An eXample
它应该意识到不管a("is[中唯一回文词的大小写=37=]") 也大于 revc (此时为 0),所以 "Isi" 应该复制到 rev.
但是它发现“eXample”是一个回文词。此外,出于某种原因,它将“eXample”的反向形式复制到 rev 中。这是为什么?
strrev()
就地更改传递的 char[]
的内容,然后 return 指向相同 char[]
的指针。它不会像您的代码假设的那样分配新字符串。因此,语句:
stricmp(strrev(v[i]), v[i])
将总是 return 0,因为您正在将v[i]
的内容与其自身进行比较。
要执行您正在尝试的操作,您需要先将 v[i]
的内容单独复制到另一个 char[]
,然后您可以反转副本并将其与内容进行比较原来的v[i]
,例如:
bool is_palindrome(const char* s)
{
char rev[256];
strcpy(rev, s);
return stricmp(strrev(rev), s) == 0;
}
char a[256], longest[256], v[101][256], sep[]=" :;.,";
int n = 0, longestc = 0;
cin.get(a, 256);
char *p = strtok(a, sep);
while (p && n < 101) {
strcpy(v[n++], p);
p = strtok(NULL, sep);
}
for(int i = 0; i < n; ++i) {
int len = strlen(v[i]);
if (len > longestc && is_palindrome(v[i])) {
strcpy(longest, v[i]);
longestc = len;
}
}
cout << longest;
如果完全去掉 v[]
数组和第二个循环,可以进一步简化,因为它们是多余的:
bool is_palindrome(const char* s)
{
char rev[256];
strcpy(rev, s);
return stricmp(strrev(rev), s) == 0;
}
char a[256], longest[256], sep[]=" :;.,";
int longestc = 0;
cin.get(a, 256);
char *p = strtok(a, sep);
while (p) {
int len = strlen(p);
if (len > longestc && is_palindrome(p)) {
strcpy(longest, p);
longestc = len;
}
p = strtok(NULL, sep);
}
cout << rev;
但是,我不推荐在 C++ 中使用这种 C 编码风格,您确实应该改用 C++ 功能,例如:
#include <string>
#include <string_view>
#include <algorithm>
#include <ctype>
bool is_palindrome(const std::string_view& s)
{
return std::equal(s.begin(), s.begin() + s.size()/2, s.rbegin(),
[](char a, char b) { return tolower(a) == tolower(b); }
);
}
std::string a;
std::getline(cin, a);
std::string_view v = a, word, longest;
std::string_view::size_type start = 0, end;
do {
end = vec.find_first_of(" :;.,", start);
if (end == std::string_view::npos) {
word = v.substr(start);
start = end;
} else {
word = v.substr(start, end-start);
start = end + 1;
}
if (word.size() > longest.size() && is_palindrome(word)) {
longest = word;
}
}
while (start != std::string_view::npos);
cout << longest;
PD:我被迫学习“strrev()”,因为这是我学士学位的一部分,请不要考虑推荐我“reverse()”。
int n = 0, str, revc=0;
char a[256], v[101][21], *p, sep[]=" :;.,", rev[256];
cin.get(a, 256);
p = strtok(a, sep);
while(p){
strcpy(v[n++], p);
p = strtok(NULL, sep);
}
for(int i = 0; i < n; i++){
str = strlen(v[i]);
if(stricmp(strrev(v[i]), v[i]) == 0 && str > revc){
strcpy(rev, v[i]);
revc = str;
}
}
cout << rev;
代码解释&遇到的问题
**这段代码的目的是找到数组(a)中最长的回文词
代码的第一部分标记了整个“a”数组,分隔符为“sep”。 第二部分代码在v中查找是否有回文词;例如,如果 a 是:
121 hellO WorlD; this Isi An eXample
它应该意识到不管a("is[中唯一回文词的大小写=37=]") 也大于 revc (此时为 0),所以 "Isi" 应该复制到 rev.
但是它发现“eXample”是一个回文词。此外,出于某种原因,它将“eXample”的反向形式复制到 rev 中。这是为什么?
strrev()
就地更改传递的 char[]
的内容,然后 return 指向相同 char[]
的指针。它不会像您的代码假设的那样分配新字符串。因此,语句:
stricmp(strrev(v[i]), v[i])
将总是 return 0,因为您正在将v[i]
的内容与其自身进行比较。
要执行您正在尝试的操作,您需要先将 v[i]
的内容单独复制到另一个 char[]
,然后您可以反转副本并将其与内容进行比较原来的v[i]
,例如:
bool is_palindrome(const char* s)
{
char rev[256];
strcpy(rev, s);
return stricmp(strrev(rev), s) == 0;
}
char a[256], longest[256], v[101][256], sep[]=" :;.,";
int n = 0, longestc = 0;
cin.get(a, 256);
char *p = strtok(a, sep);
while (p && n < 101) {
strcpy(v[n++], p);
p = strtok(NULL, sep);
}
for(int i = 0; i < n; ++i) {
int len = strlen(v[i]);
if (len > longestc && is_palindrome(v[i])) {
strcpy(longest, v[i]);
longestc = len;
}
}
cout << longest;
如果完全去掉 v[]
数组和第二个循环,可以进一步简化,因为它们是多余的:
bool is_palindrome(const char* s)
{
char rev[256];
strcpy(rev, s);
return stricmp(strrev(rev), s) == 0;
}
char a[256], longest[256], sep[]=" :;.,";
int longestc = 0;
cin.get(a, 256);
char *p = strtok(a, sep);
while (p) {
int len = strlen(p);
if (len > longestc && is_palindrome(p)) {
strcpy(longest, p);
longestc = len;
}
p = strtok(NULL, sep);
}
cout << rev;
但是,我不推荐在 C++ 中使用这种 C 编码风格,您确实应该改用 C++ 功能,例如:
#include <string>
#include <string_view>
#include <algorithm>
#include <ctype>
bool is_palindrome(const std::string_view& s)
{
return std::equal(s.begin(), s.begin() + s.size()/2, s.rbegin(),
[](char a, char b) { return tolower(a) == tolower(b); }
);
}
std::string a;
std::getline(cin, a);
std::string_view v = a, word, longest;
std::string_view::size_type start = 0, end;
do {
end = vec.find_first_of(" :;.,", start);
if (end == std::string_view::npos) {
word = v.substr(start);
start = end;
} else {
word = v.substr(start, end-start);
start = end + 1;
}
if (word.size() > longest.size() && is_palindrome(word)) {
longest = word;
}
}
while (start != std::string_view::npos);
cout << longest;