在 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;