使用自定义排序函数对向量<string>中的字符串进行排序时出现分段错误

时间:2015-10-01 13:04:19

标签: c++ sorting stl stdvector

我正在尝试对包含字符串的向量进行排序。我有以下主函数的代码

int size;
cin >> size;
vector<string> s;
cout << "READ" << endl;
for (int i = 0; i<size; i++)
{
    string str;
    cin >> str;
    s.push_back(str);
}
cout << "READ" << endl;

cout << "Passed" << endl;
sort(s.begin(), s.end(), comp);

for (int i = 0; i<size; i++)
{
    string st = s.at(I);
    cout << st << endl;
}


return 0;

comp函数代码是

bool comp(string s1, string s2)
{
    if (s1.empty() or s2.empty())
        return false;

    int l = s1.length();
    for (int i = 0; i<l; i++)
    {
        if (s1[i] > s2[i])
            return true;
    }
    return false;
}

但是对于这个输入我得到了一个分段错误

46
lnpxeemwlqlzpxrmrmwbseqfnpkzaafdnukixaopcfvhqw
dhfhhoyhhzleldljmirjbqagcleivzomlpanqzsmqnrzij
zcsrvgqlmrgknqhwtcqzyldjanlczysnspvusziqtazjlu
idiknfqdygrwhvdzperlvgueqhuezsrwzztlodqgipnqzb
zjfyxbghvdecpzhvoxzojcpciaspyoeaetimmoccjqxtmv
mxwnhdyjutecwbrxdjmrbdjvbzprgnekvnvhxnuvekoflo
jjbjxzuaafatzdwlnzcorkiagrwzvrmjqqbdlmgyewzsea
bmvyqojhnbfrypiiwvtgifmqqdcuilohbfvkqjhlcwsfyo
zrbjhsrxnllmsdfqurkjfomwsvgfepwttohojxmrhexpmy
hcdxtucpeptgqhckpdxdcgpvhkiuucvwbuhtmbskqdlasw
rtocxkyrsrbluwvpfkekqkdwncvozfgmcrswpksiqmfnnl
xawlpinqjstxvrqvsugbvszhibbcmbdwktgwjlezakyqrr
cfghwolkahdafrcuufklziipmtkhuxdrxqlavcrxavxuas
plcsutiemkgfunhpyeiuvxwjppzsopglcyhgidsyhjnutp
vyyrbmfyfwpcowlpytmkvsyrzgiausrulsxtwysjgpgtqi
bsoknggdytplubxzjczatotnpovriwibeamjfnyxibvama
imkshtavbjpnkafuxwbzpiqlnnotrxmjepzeuwtuewtqab
ttjzqrcdcofkljaevmauexsxlkrxuanxgrsmsrxckixpoz
aocndkatjggduuyiksgmovthyoomrfsaxlnjouszxxoqtc
ahmkgizkvsbrqyricbtnpvpnibvgvnnrnqphkstvcjsbli
biasqbcofwdgabnipodjkriiyqlhaddpegkmydutcyoksk
avyaodwtgbdsnhheoearlinfcadeteiiudobbvqdqizcry
mhdekyvubghealrenyshjcjuhxxzimsgvukcdfdbjramzq
ayrzjanrebdgowsngullkgyvlgqzjexebleigxvgwjnbyf
vcpnclkhoawabjlhfnrncxfswjjmpxqcwoeqpyaitwdrjf
ghngenuvshwuaubahlzazwmgnsmtzyqfvvoxnhiufhxpac
ljrwslmgjilvdommuvpebcznjalxuazyujtzpewdbxjnwj
jqirnjnheowbioheyleyhkrcyfxuweyipumfojetmvomuz
vnnlsozyplofqkxfwcmlyntfrhspvbscocodlejqrymdeu
lgjcimksyragrhhagkmlnaysfxzswxfkhqzrhjlgkemmhp
weoxhopddcyiiikwblqvvcxcuxkebhywdacpmjrlkosxmw
bwcxxsytqdpybjxyqgmggitkgpkiytnwprsnxrygryxigo
qtwyleqxqflmaudekmdmgscfvjfwkchacxmokxrcfgwnhl
dgcmvhgnzigmrxougsbhwdhugyvloaqlliybbzkttmolln
jqmrfoyhwxbiyvzntvxozfswwjbeybahggfjrrzzhbapyi
oxbjadgrttqnfbevqolflhdpmgwgudhwfeebauqhhygvnt
kwmqirrljycddqcvjanibiarpcjjqiuvkdbdyzogbcixah
yyykebcfsnixcjdbkxtqvqynafmtuvoepeayiaqinvmjen
lsyxwgpfxlfkxckzsjzonxkhullkatmnwwfuicgjzbnvzf
vihglfapunknuitwtcxzdwjyfwqurvsydacylgcyohrbou
olmojrovoqseuqausssdupqzhbmyblomlbbqzwgbtgyiwq
tcshhbdgxsrtxywgqahqfimbnckwdhtbzlpwevuqjyqrbd
vjmcknagopzpwrmrianbgyhyginqduwdfjgmdqttcqroof
srmfsjigydlqlgsmvgqddpqmqkjzptzwdfpjmpnvgaezlx
yphbhtrmqcnrfklqmkblvginnhxxtlnnwcfuwujdqwkvaq
jahvrihhicrqvttmdzwbemjjqnstvtudvifdvrbjxalirj

对于很多其他输入它会给出正确的结果但是对于上面的结果我得到了这个结果

READ
READ
Passed

我搜索了很多但在comp函数中找不到错误。

3 个答案:

答案 0 :(得分:2)

您的补偿方法已被破坏。

对于这两个字符串&#34; ac&#34;并且&#34; ca&#34;,comp("ac", "ca")comp("ac", "ca")一样真实。因为你在s1[i] < s2[i]时尝试下一个位置,你应立即返回假。

正如您在评论中所说,您应该使用较短的长度来处理不同长度的字符串,以避免访问过去的字符串长度时出错。

所以你的comp方法应该是:

bool comp(string s1,string s2)
{
    // empty string comes last
    if(s1.empty()) return false;
    if(s2.empty()) return true;

    // limit to shorter string length
    unsigned int l = s1.length();
    if (s2.length() < l) l = s2.length();
    for(unsigned int i=0;i<l;i++)
    {
        // if chars are different at position i return immediately
        if(s1[i] > s2[i])
            return true;        
        if(s1[i] < s2[i])
            return false;        
    }
    // shorter string comes last
    return(s1.length() >= s2.length());
}

答案 1 :(得分:2)

正如其他人所说,你的比较功能被打破了。

以下是使用std::greater<std::string>()作为比较函数的示例:

#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

int main() {
    int size;
    if (!(std::cin >> size)) return -1;

    std::vector<std::string> v;
    for (int i = 0; i < size; i++) {
        std::string str;
        if (!(std::cin >> str)) return -1;
        v.push_back(str);
    }

    std::sort(v.begin(), v.end(), std::greater<std::string>());

    for (int i = 0; i < v.size(); i++) {
        std::cout << v[i] << std::endl;
    }

    return 0;
}

输出按降序排序(test.txt包含上面的输入):

$ g++ test.cc && ./a.out < test.txt
zrbjhsrxnllmsdfqurkjfomwsvgfepwttohojxmrhexpmy
zjfyxbghvdecpzhvoxzojcpciaspyoeaetimmoccjqxtmv
zcsrvgqlmrgknqhwtcqzyldjanlczysnspvusziqtazjlu
yyykebcfsnixcjdbkxtqvqynafmtuvoepeayiaqinvmjen
yphbhtrmqcnrfklqmkblvginnhxxtlnnwcfuwujdqwkvaq
xawlpinqjstxvrqvsugbvszhibbcmbdwktgwjlezakyqrr
weoxhopddcyiiikwblqvvcxcuxkebhywdacpmjrlkosxmw
vyyrbmfyfwpcowlpytmkvsyrzgiausrulsxtwysjgpgtqi
vnnlsozyplofqkxfwcmlyntfrhspvbscocodlejqrymdeu
vjmcknagopzpwrmrianbgyhyginqduwdfjgmdqttcqroof
vihglfapunknuitwtcxzdwjyfwqurvsydacylgcyohrbou
vcpnclkhoawabjlhfnrncxfswjjmpxqcwoeqpyaitwdrjf
ttjzqrcdcofkljaevmauexsxlkrxuanxgrsmsrxckixpoz
tcshhbdgxsrtxywgqahqfimbnckwdhtbzlpwevuqjyqrbd
srmfsjigydlqlgsmvgqddpqmqkjzptzwdfpjmpnvgaezlx
rtocxkyrsrbluwvpfkekqkdwncvozfgmcrswpksiqmfnnl
qtwyleqxqflmaudekmdmgscfvjfwkchacxmokxrcfgwnhl
plcsutiemkgfunhpyeiuvxwjppzsopglcyhgidsyhjnutp
oxbjadgrttqnfbevqolflhdpmgwgudhwfeebauqhhygvnt
olmojrovoqseuqausssdupqzhbmyblomlbbqzwgbtgyiwq
mxwnhdyjutecwbrxdjmrbdjvbzprgnekvnvhxnuvekoflo
mhdekyvubghealrenyshjcjuhxxzimsgvukcdfdbjramzq
lsyxwgpfxlfkxckzsjzonxkhullkatmnwwfuicgjzbnvzf
lnpxeemwlqlzpxrmrmwbseqfnpkzaafdnukixaopcfvhqw
ljrwslmgjilvdommuvpebcznjalxuazyujtzpewdbxjnwj
lgjcimksyragrhhagkmlnaysfxzswxfkhqzrhjlgkemmhp
kwmqirrljycddqcvjanibiarpcjjqiuvkdbdyzogbcixah
jqmrfoyhwxbiyvzntvxozfswwjbeybahggfjrrzzhbapyi
jqirnjnheowbioheyleyhkrcyfxuweyipumfojetmvomuz
jjbjxzuaafatzdwlnzcorkiagrwzvrmjqqbdlmgyewzsea
jahvrihhicrqvttmdzwbemjjqnstvtudvifdvrbjxalirj
imkshtavbjpnkafuxwbzpiqlnnotrxmjepzeuwtuewtqab
idiknfqdygrwhvdzperlvgueqhuezsrwzztlodqgipnqzb
hcdxtucpeptgqhckpdxdcgpvhkiuucvwbuhtmbskqdlasw
ghngenuvshwuaubahlzazwmgnsmtzyqfvvoxnhiufhxpac
dhfhhoyhhzleldljmirjbqagcleivzomlpanqzsmqnrzij
dgcmvhgnzigmrxougsbhwdhugyvloaqlliybbzkttmolln
cfghwolkahdafrcuufklziipmtkhuxdrxqlavcrxavxuas
bwcxxsytqdpybjxyqgmggitkgpkiytnwprsnxrygryxigo
bsoknggdytplubxzjczatotnpovriwibeamjfnyxibvama
bmvyqojhnbfrypiiwvtgifmqqdcuilohbfvkqjhlcwsfyo
biasqbcofwdgabnipodjkriiyqlhaddpegkmydutcyoksk
ayrzjanrebdgowsngullkgyvlgqzjexebleigxvgwjnbyf
avyaodwtgbdsnhheoearlinfcadeteiiudobbvqdqizcry
aocndkatjggduuyiksgmovthyoomrfsaxlnjouszxxoqtc
ahmkgizkvsbrqyricbtnpvpnibvgvnnrnqphkstvcjsbli

供参考:

答案 2 :(得分:1)

这个条件:

 if (s1.empty() or s2.empty())
    return false;

不满足对comp函数的严格弱排序要求(来自https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings

  
    

如果x&lt; y,然后对于所有z,x&lt; z或z&lt;你或两者。

  

如果z为空字符串且xy不是字符串,则不会满足x < zz < y

可能的实施是:

if( s2.empty() ) return !s1.empty();
if( s1.empty() ) return false;

但我不明白为什么你不能使用std::greater std::string::comparestd::string::operator>()而不是手动实现