0

std :: list :: sort関数の使用に多くの問題があります。ほとんどの場合は機能しますが、アサーション'invalidoperator<'がスローされることがあります。この問題を調べてみると、ソート関数が厳密な弱順序に従っていないことが原因であることがわかりましたが、コードを見ると、正しいように見えるので、なぜ厳密な弱い順序に従っていないのかわかりません。何が欠けているのでしょうか。ここ?

この関数の目的は、要素のリストを丘のシステムに基づいて数式文字列に並べ替えることです。カーボンファースト、水素セカンド、その他すべてアルファベット順。FormulaStructは、完全な数式の1つの要素と量を表すだけです。

struct FormulaStruct
{
    FormulaStruct(const std::string & strSymbol, int nNum, bool bHasCarbon)
        :
            m_strSymbol(strSymbol),
            m_nNum(nNum), m_bHasCarbon(bHasCarbon)
    {
    }

    bool operator < (const FormulaStruct & rhs)
    {
        //If the symbols are equal
        if(m_strSymbol == rhs.m_strSymbol)
            return true;

        if(m_bHasCarbon)
        {       
            if(m_strSymbol == "C")
                return true;        
            else        
            if(rhs.m_strSymbol == "H")
                return false;           
        }

        return m_strSymbol < rhs.m_strSymbol;
    }

    bool operator == (const FormulaStruct & rhs)
    {
        return m_strSymbol == rhs.m_strSymbol;
    }

    std::string m_strSymbol;
    int         m_nNum;
    bool        m_bHasCarbon;
};

list<FormulaStruct> FormulaList; //A list of FormulaStructs, assumed to be filled
FormulaList.sort();

編集 bHasCarbonは、式に炭素が含まれている場合の条件です。ヒルシステムでは、式に炭素が含まれている場合は水素よりも次の炭素が必要であり、そうでない場合は水素を含むすべてがアルファベット順であるため、コードの別のセクションで指定されます。

4

2 に答える 2

2

他の回答はすでにm_strSymbol == rhs.m_strSymbol問題に対処しています。

しかし、あなたの説明(最初に「C」、次に「H」、その他すべてを順番に)に基づくと、C ++ 11を使用している場合は、次のようになります。

return std::tie(m_strSymbol != "C", m_strSymbol != "H", m_strSymbol)
    < std::tie(rhs.m_strSymbol != "C", rhs.m_strSymbol != "H", rhs.m_strSymbol);

これは、StrictWeakOrderings(ここから盗まれた)を書く簡単な方法です。

または、C ++ 11(またはBoost pre-C ++ 11)がない場合は、次のようにすることができます。

// order of checks here is important, in case both are "C"
if(rhs.m_strSymbol == "C")
    return false;
if(m_strSymbol == "C")
    return true;
// neither symbol is "C"
if(rhs.m_strSymbol == "H")
    return false;
if(m_strSymbol == "H")
    return true;
// neither symbol is "C" or "H"
return m_strSymbol < rhs.m_strSymbol;

私はそれを正しく行ったと確信していますが、上記の記事で述べたように、手動で行うとエラーが発生しやすく、おそらく避ける必要があります...また、これは文字列比較の数を減らすためにさらに最適化することができます、バグを導入し、コードを難読化するリスクがあります。

しかし、m_bHasCarbonが何を意味し、どのような効果があるのか​​は不明なので、これが必要かどうかはわかりません。

于 2013-02-28T02:45:57.307 に答える
1
//If the symbols are equal
if(m_strSymbol == rhs.m_strSymbol)
        return true;

Meaning it is true for both a<b and b<a if the symbols are equal.

Perhaps you should return false, since a==b and thus !a<b, in this case.

Also your second set of compares are confusing.. what is m_bHasCarbon.

于 2013-02-28T02:16:40.710 に答える