【问题标题】:Sorted strings in C++ don't compare correctly?C ++中的排序字符串不能正确比较?
【发布时间】:2014-02-21 20:58:53
【问题描述】:

基本上,我有两个列表。列表A 有术语,列表B 有已打乱的术语。我试图通过复制A 来解读B,对其中的每个字符串进行排序,然后对B 中的字符串进行排序,并将它们与A 的排序版本相匹配。然后我可以从已排序的A 中获取索引,并通过将相同的索引放入A 中找到原始索引。

到目前为止,我的代码看起来不错,但字符串永远不会彼此相等。我已经尝试了所有我知道的比较形式,现在我在做str1.compare(str2) == 0

我的代码:
我有vector<string> linesvector<string> keywords。然后我有vector<string> sorted_kws,即keywords,所有内容都已排序。

// Finding matching strings
for (int i = 0; i < lines.size(); i++) {
    for (int j = 0; j < sorted_kws.size(); j++) {
        if (lines[i].compare(sorted_kws[j]) == 0)
            cout << keywords[j] << ",";
    }
}
cout << endl;

我在这里做错了什么?
我也尝试过使用std::find,但这也没有用。
此外,我打印了所有内容以确保它看起来正确。字符串完全相同,并且绝对应该彼此相等,但它们不相等。

【问题讨论】:

  • 您是否尝试使用调试器?
  • 请发布一个最小但完整的示例来演示该问题。

标签: c++ string comparison string-comparison


【解决方案1】:

如果没有看到更多代码,就很难(即不可能)准确地猜出问题所在。也就是说,让基本想法发挥作用当然是可能的。

我想我会通过定义一个存储字符串的原始形式和排序形式的类来做到这一点。当你进行比较时,它会根据排序后的形式进行比较,但是当你将它写入流时,它会显示原始字符串:

class sorted_string {
    std::string sorted;
    std::string original;
public:
    sorted_string(char const *input) :sorted(input), original(input) {
        std::sort(sorted.begin(), sorted.end());
    }

    friend std::ostream &operator<<(std::ostream &os, sorted_string const &s) {
        return os << s.original;
    }

    bool operator<(sorted_string const &other) const { 
        return sorted < other.sorted; 
    }
};

使用它,其余的代码变得非常简单:

int main() {
    // create two sets of input strings:
    std::set<sorted_string> in1{ "xzy", "bac", "dffed", "iii", "iji" };
    std::set<sorted_string> in2{ "yxz", "cab", "yyy", "ffedd", "iop" };

    // print out the intersection based on sorted comparison:
    std::set_intersection(
        in1.begin(), in1.end(),
        in2.begin(), in2.end(),
        std::ostream_iterator<sorted_string>(std::cout, "\n"));
}

我想你可以使用std::map&lt;std::string, std::string&gt; 来做同样的事情,使用字符串的排序版本作为键,原始版本作为映射值,但至少临时看起来这可能会导致更多工作而不是更少。

【讨论】:

    【解决方案2】:

    很难确切地知道你想要做什么,但是如果你有两个排序的向量,并且你想知道两者中的匹配项,那么你可以使用 std::set_intersection() 而不是循环。

    #include <algorithm>
    #include <iterator>
    #include <string>
    #include <vector>
    #include <iostream>
    
    // assume v1 and v2 are sorted
    typedef std::vector<std::string> StringVect;
    StringVect getDifferences(const StringVect& v1, 
                              const StringVect& v2)
    {
       StringVect theDiff;
       std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), 
                             std::back_inserter(theDiff));
       return theDiff;
    }
    
    int main()
    {
        StringVect v1;
        v1.push_back("a");
        v1.push_back("b");
        v1.push_back("c");
        StringVect v2;
        v2.push_back("a");
        v2.push_back("c");
        std::sort(v1.begin(), v1.end());
        std::sort(v2.begin(), v2.end());
        StringVect dif = getDifferences(v1, v2);
        std::copy(dif.begin(), dif.end(), 
                  std::ostream_iterator<std::string>(std::cout, " "));
    }
    

    输出是:

    一个c

    【讨论】:

      【解决方案3】:

      想通了。当所有的字符串都有愚蠢的"\r\n"s 时,我被"\n" 分裂了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        相关资源
        最近更新 更多