C++运行时错误:无符号偏移量的增加?

rhfm7lfc  于 2023-08-09  发布在  其他
关注(0)|答案(5)|浏览(123)

我写了下面的代码来检查文本是否是回文,我在leetcode上运行它,我得到了错误:

class Solution {
public:
    bool isPalindrome(string s) {
        int l=0,r=s.length()-1;
        while(l<r)
        {
            while (!isalpha(s[r]))
            {
                --r;
            }
            while (!isalpha(s[l]))
            {
                ++l;
            }
            if (tolower(s[r])!=tolower(s[l]))
                return false;
            --r;
            ++l;
        }
        return true;
    }
};

字符串
第1061行:Char 9:运行时错误:将无符号偏移添加到0x 7 ffc 7 cc 10880溢出到0x 7 ffc 7 cc 1087 f(basic_string.h)摘要:未定义行为消毒剂:/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../include/c++/9/bits/basic_string.h:1070:9
我的代码有什么问题?

b5buobof

b5buobof1#

你越界了

while (!isalpha(s[r]))

字符串
还有这里

while (!isalpha(s[l]))


r可以变为负值,l可以变为>= s.length()
您应该添加一些检查,如

while (l < r && !isalpha(s[r]))


和/或

while (l < r && !isalpha(s[l]))


这一行同样的问题

if (tolower(s[r])!=tolower(s[l]))


这应该是

if (l < r && tolower(s[r])!=tolower(s[l]))

不同的方式(C++20)

一种不同的方法是使用以下命令从s中擦除所有非字母字符

std::erase_if(s, [](char c) { return !isalpha(c); });


并删除内部的while循环。

6fe3ivhb

6fe3ivhb2#

我认为你已经非常接近解决方案了。这里的陷阱是:

  • 在循环中多次修改循环控制变量
  • (因此)您在更改其值后使用循环控制变量,而无需进一步检查。

修复这类问题的简单方法是为每个迭代执行一个操作。你可以使用“else”来实现这一点。

class Solution {
public:
    bool isPalindrome(string s) {
        int l=0,r=s.length()-1;
        while(l<r)
        {
            if(!isalpha(s[r]))
            {
                --r;
            }
            else if(!isalpha(s[l]))
            {
                ++l;
            }
            else if (tolower(s[r])!=tolower(s[l]))
            {
                return false;
            }
            else
            {
                --r;
                ++l;
            }
        }
        return true;
    }
};

字符串

yi0zb3m4

yi0zb3m43#

一个类似的修改方法可以解决这个问题,只要遇到任何非字母数字字符,就继续循环。这里:

bool isPalindrome(string s) {    
    int start=0,end=s.length()-1;
    
    while(start<=end){
        if(!isalpha(s[start])  && !isdigit(s[start])){
            start++;
            continue;
        }
        
        if(!isalpha(s[end]) && !isdigit(s[end])){
            end--;
            continue;
        }
        
        if(tolower(s[start])!=tolower(s[end])){
            return false;
        }
        
        start++;
        end--;
    }
    
    return true;

}

字符串

ttcibm8c

ttcibm8c4#

在某些情况下你会越界。所以你可以尝试下面的代码没有错误和内存泄漏。

bool isPalindrome(string s) {
  string a="";
  for(int i=0 ; i<s.length() ; i++)
  {
   if(s[i]>=65 && s[i]<=90)
        a+=(s[i]+32);
        else if(s[i]>=97 && s[i]<=122)
        a+=s[i];
        else if(s[i]>='0' && s[i]<='9')
        a+=s[i];
    }
    int start=0, end=a.length()-1;
    while(start<end)
    {
        if(a[start++]!=a[end--])
        return false;
    }
    return true;
}

字符串

polkgigr

polkgigr5#

正如其他人所说,你正在耗尽债券。下面是一个简化的解决方案,它不会耗尽债券,也没有if-then-else意大利面条代码:

bool IsPalindrome(const char *s)
{
    int forward, totLen, halfLen, backward;

    totLen = (int)strlen(s);    // Total length
    halfLen = totLen / 2;       // Half the length, if totLen is odd, will ignore the character in the middle

    for (forward = 0; forward < halfLen; forward++) // Index from front of string
    {
        backward = totLen - (forward + 1);          // Corresponding index from back of string
        if (s[forward] != s[backward])
            return false;                           // Not a palindrome
    }
    return true;    // Got one!
}

字符串

相关问题