Meryl Silverburgh wrote:
On 2/18/07, Pavol Droba
wrote: Hi,
Meryl Silverburgh wrote:
Thanks for your idea.
I have cases like this:
/1/1 /1/2/3/2
Since the first string /1/1 is smaller than the /1/2 (1 is < 2) of the /1/2/3/2, I should able to stop comparison by looking at the 4th character (/1/2) of '/1/2/3/2'.
So for cases like that, I would like to stop as soon as i can tell one string is shorter than the other, instead of splitting the whole string.
This is exactly what would happen you use the second approach I gave you. Constructing the iterator_range from the split iterator does not perform any actual searching, and lexicographical_compare stops on the first possible index (i.e on the first position where inputs are different).
You can even throw away the vector, and directly create an iterator_range from the split_iterator. This way you may spare some unnecessary tokenization.
typedef split_iteratorstring::const_iterator string_split; iterator_range
r1( make_split_iterator(s1, is_any_of("/")), string_split()) iterator_range
r2( make_split_iterator(s2, is_any_of("/")), string_split()) if(lexicographical_compare(r1, r2, integer_compare)) { // s1 is less } Regards, Pavol
Pavol,
Thanks for your help. I am trying your second approach. But I am having compilation error in this line: iterator_range
r1( make_split_iterator(s1, is_any_of("/")), string_split()); error: ../test.cpp:18: error: no matching function for call to `boost::algorithm::iterator_range ::iterator_range(boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator , string_split)' /usr/include/boost/algorithm/string/iterator_range.hpp:89: note: candidates are: boost::algorithm::iterator_range<IteratorT>::iterator_range(const boost::algorithm::iterator_range<IteratorT>&) [with IteratorT = string_split] /usr/include/boost/algorithm/string/iterator_range.hpp:85: note:
Complete program: #include <iostream> #include <string>
#include "boost/algorithm/string/find_iterator.hpp" #include "boost/algorithm/string/classification.hpp" using namespace std; using namespace boost::algorithm;
typedef split_iteratorstring::const_iterator string_split;
int main(int argc, char **argv) { cout << "hello world" << endl;
string s1("/1/1/2"); string s2("/1/1/3");
iterator_range
r1( make_split_iterator(s1, is_any_of("/")), string_split()); iterator_range
r2( make_split_iterator(s2, is_any_of("/")), string_split()); if(lexicographical_compare(r1, r2, integer_compare)) { cout << " s1 is less " << endl; } else { cout << " s2 is less " << endl; } }
}
The problem is with template instantiation. Since you are passing "string" and not "const string" as an argument to make_split_iterator, the resulting type is actualy split_iteratorstring::iterator. This is not the same (nor convertible) to split_iteratorstring::const_iterator. So the simple fix would be to change the definition of the string_split to split_iteratorstring::iterator. In addition, you will need to implement integer_compare. I have not included it in may mail. Please, don't take my code as 100% correct. I didn't actualy compile it, I just wanted to gived you an idea which way to go. Anyway, I'll be glad to help you if you have any further questions. Regards, Pavol.