【问题标题】:std::stable_sort vs std::sort [duplicate]std::stable_sort vs std::sort [重复]
【发布时间】:2020-09-14 02:17:14
【问题描述】:

https://leetcode.com/problems/largest-number/

当我解决上述问题时,我遇到了std::sort() 给我一个运行时错误的情况,但是用std::stable_sort() 替换它然后没有运行时错误。为什么?

行以右侧箭头符号突出显示

代码:

class Solution {
public:
    string reverse(string str)
    {
        int n=str.length();
        for(int i=0;i<n/2;i++)
        {
            swap(str[i],str[n-i-1]);
        }
        return str;
    }

    static bool comp(string s1,string s2)
    {
        int min_val=min(s1.length(),s2.length());
        int i=0;
        bool flag=false;
        for(;i<min_val;i++)
        {
            if((s1[i]-'0')==(s2[i]-'0'))
            {
                flag=true;
                continue;
            }

            return (s1[i]-'0')>(s2[i]-'0');
        }

        if(flag==true && s1.length()==s2.length())
        {
            return s1==s2;
        }

        string s1_temp=s1;
        string s2_temp=s2;
        s1_temp+=s2;
        s2_temp+=s1;

        return s1_temp>s2_temp;
    }

    string largestNumber(vector<int>& nums)
    {
        string str="";
        vector<string> inp;

        for(int i=0;i<nums.size();i++)
        {
            string temp="";
            long long int num=nums[i];
            if(num!=0)
            {
                while(num!=0)
                {
                    temp+=((num%10)+'0');
                    num/=10;
                }
            }
            else
            {
                temp+=(num+'0');
            }

            inp.push_back(reverse(temp));
        }

        stable_sort(inp.begin(),inp.end(),comp); // <-- This Line

        string res="";

        for(int i=0;i<inp.size();i++)
        {
            res+=inp[i];
        }
        cout<<"yes"<<endl;
        if(res[0]=='0')
        {
            return "0";
        }

        return res;
    }
};

测试用例:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0]

谁能告诉我发生这种情况的原因?

【问题讨论】:

  • 常规排序有什么错误?
  • 为什么需要自定义比较功能?你不能完全离开comp吗?
  • ** 以下是运行时错误 **:第 431 行:字符 55:运行时错误:指针索引表达式以 0xbebebebebebebe 为基数溢出到 0x7d7d7d7d7d7d7d7c (basic_string.h)
  • 您的代码不完整。 main 在哪里?你的#includes 在哪里?

标签: c++ string sorting stl stable-sort


【解决方案1】:

这实际上是一个非常有趣的错误!我没有测试这是否是 leetcode 特定的问题,但是在 leetcode 上使用sort() 运行此代码,我们会收到以下错误:

Line 431: Char 55: runtime error: pointer index expression with base 0xbebebebebebebebe overflowed to 0x7d7d7d7d7d7d7d7c (basic_string.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/basic_string.h:440:55

这似乎表明我们由于某种原因内存不足。此代码适用于stable_sort() 但不适用于sort() 的事实表明,这可能与“stable_sort 保留具有等效值的元素的相对顺序”(http://www.cplusplus.com/reference/algorithm/stable_sort/)这一事实有关。

与此相关的代码行在这里

if(flag==true && s1.length()==s2.length())
{
    return s1==s2;
}

确实,如果我们将其更改为

if(flag==true && s1.length()==s2.length())
{
    return s1!=s2;
}

这不会影响结果,因为如果此时flag == true 和两个字符串的长度相同,那么它们都是等价的,并且交换字符串位置不会影响结果。

但是我们绕过了错误。 @Vikram Keswani 我希望这能解决您的问题。就我个人而言,我也会将 comp() 函数中的代码替换为 return s1 &gt; s2;,它应该提供与您拥有的代码相同的行为。

附言我将把拼图的部分留在这里,但如果有更有经验的人(或者当我有更多时间)想进一步调查这个神秘的记忆问题,那就太好了。

顺便说一句,在 leetcode 上重现此错误所需的最小长度输入是 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],这是 17 个 0(一个奇怪的数字)。

【讨论】:

  • 是的,这就是答案。 std::sort 要求比较器满足某些 requirements。具体来说,它必须是严格的弱排序,并且必须满足comp(a,a)==false。换句话说,一个元素不能与它自己比较为真。 OP 的功能不能满足这一点(comp("0", "0") 返回真)。您的修复解决了这个问题,并使比较器符合要求。
猜你喜欢
  • 2014-07-22
  • 2010-10-23
  • 2012-05-26
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
相关资源
最近更新 更多