Say `string :: operator ==` to start the comparison at the end of the line

Is it possible (relatively) easy / std β„’ to start the comparison at the end of the line, or should I write my own function for this? Of course, this would be relatively simple, but, nevertheless, I could trust the standard library implementation over mine any day.

The end of the line is almost unique, and the front is quite common, and the only reason I need this "optimization".

Thanks!

+7
c ++ string compare
source share
6 answers

Best of all, I can imagine that str1.size() == str2.size() && std::equal(str1.rbegin(), str1.rend(), str2.rbegin())

+18
source share

You can use std :: equal in combination with std :: basic_string :: reverse_iterator (rbegin, rend).

However, this only matters if the strings are the same length (so you need to check the sizes first) and only for equality of strings (since the most significant difference will be the last compared when repeating).

Example:

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

Depending on how many lines (and your compiler) you might be better off sticking with operator== . In Visual C ++ v10, which boils down to calling memcmp via char_traits::compare , which (when optimized) will compare ranges of target bytes in chunks, perhaps as many bytes at a time as fit in the register (4/8 for 32 / 64-bit).

 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)); } 

Meanwhile, std::equal (the nicest alternative) does a byte comparison by byte. Does anyone know if this will be optimized in the same way since they are reverse iterators? In the best case, alignment processing is more complex since the start of the range is not guaranteed to be well aligned.

 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); } 

See @greyfade's answer here for some color in GCC.

+3
source share

If you want to cancel it first, I would suggest reverse () to collapse the string first and then start comparing with string.compare () or use your own algorithm. However, the reverse () function takes some time and is intensively processed by the processor, so I suggest your own function to handle this. Start the loop with i equal to string.length (), and then recount with -i and 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); 
+2
source share

You must write your own function for yourself. You can undo, as Lost says, but that would not be an optimization if you did not save this return line and compare it several times. Even then, it would not be better than writing your own, simply repeating the lines in reverse order.

0
source share

I see two options:

  • Write your own comparison function and call it.

  • Write a wrapper class around std :: string and implement operator== for this class to have the desired behavior.

The second is probably too large.

0
source share

All Articles