【问题标题】:std::list Strict Weak Orderingstd::list 严格弱排序
【发布时间】:2013-02-14 02:18:49
【问题描述】:

我在使用 std::list::sort 函数时遇到了很多麻烦,它在大多数情况下都可以工作,但是每隔一段时间它就会抛出一个断言“无效运算符

该函数的目的是根据希尔系统将元素列表排序为公式字符串,即。碳第一,氢第二,所有其他按字母顺序排列。 FormulaStruct 仅表示完整公式中的单个元素和数量。

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 是当公式中有碳时的条件,因为希尔系统要求如果公式中有碳,那么接下来是氢,否则一切都是按字母顺序排列的,包括氢,这在我的代码的另一部分中规定。

【问题讨论】:

  • 符号相等时返回true。这是为什么呢?
  • @jogojapan 是对的,想象两个对象ab 具有相同的符号:您的操作员同时给出a &lt; bb &lt; a...
  • 您的 m_bHasCarbon 条件不清楚,您能描述一下您要做什么吗?
  • 抛出一个无效的 '

标签: c++ list stl strict-weak-ordering


【解决方案1】:

其他答案已经解决了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 的简单方法(从here 窃取)

或者,如果你没有 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 是什么意思以及应该有什么效果,所以我不确定这是否是你需要的。

【讨论】:

  • 这很好用,我仍在为整个“严格弱排序”规则而苦苦挣扎,我使用 Visual Studio 2010,我不确定 std::tie 是否因为它不起作用而进入编译器对我来说,所以我使用了第二个版本,它运行良好。
  • 查看最重要的答案here 了解严格弱排序需要满足的属性。
  • 另外,我相信它对你有用,但我忽略了m_bHasCarbon,仍然无法判断它在这里是否重要。
  • 只有在没有碳的情况下才重要,例如使用 CHAR 会正确排序,但去除碳后,它将被排序为 ArH
  • m_bHasCarbon 特定于每个FormulaStruct 还是整个FormulaList 都相同?如果是后者,它可能不应该是FormulaStruct 的成员变量——这令人困惑
【解决方案2】:
//If the symbols are equal
if(m_strSymbol == rhs.m_strSymbol)
        return true;

这意味着如果符号相等,a&lt;bb&lt;a 都为 true。

也许你应该return false,因为a==b!a&lt;b,在这种情况下。

您的第二组比较也令人困惑.. m_bHasCarbon 是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-04
    • 2010-11-20
    • 1970-01-01
    • 2016-02-04
    • 2019-06-09
    • 2015-09-20
    • 2010-11-02
    • 1970-01-01
    相关资源
    最近更新 更多