告诉`string :: operator ==`开始在字符串后面进行比较

时间:2010-11-30 19:50:07

标签: c++ string compare

是否可以/(相对)轻松/ std™开始在字符串后面进行比较,还是应该为此编写自己的函数?当然,它会相对简单,但我仍然相信我的标准库实现在任何一天。

字符串的结尾几乎是唯一的,前面很常见,这是我需要这种“优化”的唯一原因。

谢谢!

6 个答案:

答案 0 :(得分:18)

我能想到的最好的是str1.size() == str2.size() && std::equal(str1.rbegin(), str1.rend(), str2.rbegin())

答案 1 :(得分:3)

你可以将std :: equal与std :: basic_string :: reverse_iterator(rbegin,rend)结合使用。

但是,仅当字符串具有相同的长度(因此您需要首先检查大小)并且仅用于字符串的相等时才是相关的(因为最重要的差异将是迭代时最后的比较)。

示例:

bool isEqual = s1.size() == s2.size() && std::equal( s1.rbegin(), s1.rend(), s2.rbegin());

答案 2 :(得分:3)

根据字符串的长度(以及编译器),最好坚持使用operator==。在Visual C ++ v10上,通过memcmp减少到char_traits::compare调用,这是(在优化时)将比较块中的目标字节范围,可能一次只有多少字节符合寄存器(4/8表示32/64位)。

static int __CLRCALL_OR_CDECL compare(const _Elem *_First1, const _Elem *_First2,
    size_t _Count)
    {   // compare [_First1, _First1 + _Count) with [_First2, ...)
    return (_CSTD memcmp(_First1, _First2, _Count));
    }

同时,std::equal(最好的替代方案)进行逐字节比较。有人知道这是否会以相同的方式进行优化,因为它们是反向迭代器?最好的是,对齐处理更复杂,因为范围的开始并不能保证良好对齐。

template<class _InIt1,
    class _InIt2> inline
    bool _Equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
    {   // compare [_First1, _Last1) to [First2, ...)
    for (; _First1 != _Last1; ++_First1, ++_First2)
        if (!(*_First1 == *_First2))
            return (false);
    return (true);
    }

有关GCC的某些颜色,请参阅@ greyfade的回答here

答案 3 :(得分:2)

如果你想首先反转它,我建议首先反向()反转字符串,然后使用string.compare()开始比较或使用你自己的算法。但是,reverse()确实需要一段时间,并且是处理器密集型的,所以我建议你自己的功能来处理这个。用i等于string.length()开始循环,然后使用--i和compare进行倒计时。

function stringCompFromBack(string str1, string str2)
{
    if (str1.length() != str2.length)
    {return false;}

    for(int i = str1.length() ; i > 0; --i)
    {
        if(str1[i] != str2 [i])
        {return false;}
    }
    return true;
}

string str1 = "James Madison";
string str2 = "James Ford";
bool same = stringCompFromBack(str1, str2);

答案 4 :(得分:0)

你应该为此编写自己的函数。你可以像Lost所说的那样反转,但这不会是一个优化,除非你保持反转的字符串和多次比较。即使这样,编写自己的东西也不会改进,只需反向迭代字符串。

答案 5 :(得分:0)

我看到两个选项:

  1. 编写自己的比较函数并调用它。

  2. 写一个包装类 std :: string,并为该类实现operator==以获得所需的行为。

  3. 第二种可能是矫枉过正。