Boost logo

Boost Users :

From: Pavol Droba (droba_at_[hidden])
Date: 2007-02-19 16:27:14


Meryl Silverburgh wrote:
> On 2/18/07, Pavol Droba <droba_at_[hidden]> 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_iterator<string::const_iterator> string_split;
>>>> iterator_range<string_split> r1(
>>>> make_split_iterator(s1, is_any_of("/")), string_split())
>>>>
>>>> iterator_range<string_split> 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<string_split> 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<string_split>::iterator_range(boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*,
> std::basic_string<char, std::char_traits<char>, std::allocator<char> >
>>> , 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_iterator<string::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<string_split> r1(
> make_split_iterator(s1, is_any_of("/")), string_split());
>
> iterator_range<string_split> 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_iterator<string::iterator>. This is
not the same (nor convertible) to split_iterator<string::const_iterator>.

So the simple fix would be to change the definition of the string_split
to split_iterator<string::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.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net