Leonid
Leonid

Reputation: 23480

Sorting strings in C++ using operator <

The following array is given in C++ code:

char strings[105][105];

What is the correct way to write operator< to sort the strings using STL sort function and is it possible at all?

Upvotes: 1

Views: 2040

Answers (4)

UncleBens
UncleBens

Reputation: 41351

You can't overload operator< for pointers, but you don't need to, since std::sort can accept any comparison function (or functor).

Another problem is that the sort algorithm cannot swap arrays, because they are not assignable. But you can sort an array of pointers into the two-dimensional array (leaving the original array as it is).

#include <algorithm>
#include <cstring>
#include <cstdio>

bool compare_cstring(const char* a, const char* b)
{
    return strcmp(a, b) < 0;
}

int main()
{
    const int count = 5;
    char strings[count][10] = { "One", "Two", "Three", "Four", "Five" };
    char* sorted_view[count];
    for (int i = 0; i != count; ++i) {
        sorted_view[i] = strings[i];
    }

    std::sort(sorted_view, sorted_view + count, compare_cstring);
    for (int i = 0; i != count; ++i) {
        puts(sorted_view[i]);
    }
}

Upvotes: 1

Cubbi
Cubbi

Reputation: 47448

Assuming you really do need to sort a 2D array row-wise, it's a bit difficult to make std::sort() do this for you, even given a working comparer functor: it would need some sort of iterator adapter.

However, you can easily use other in-place sorting algorithms, such as selection sort:

#include <iostream>
#include <algorithm>
#include <string>

template<int N>
bool char_array_less(const char(&l)[N], const char(&r)[N])
{
   return std::char_traits<char>::compare(&l[0], &r[0], N) < 0;
// for a more general solution
// return std::lexicographical_compare(&l[0], &l[0]+N, &r[0], &r[0]+N);
}

template<int N>
void swap_char_arrays( char(*l)[N], char(*r)[N])
{
    std::swap_ranges(&(*l)[0], &(*l)[0]+N, &(*r)[0]);
}

const int ROWS = 105;
const int COLS = 105;
int main()
{
    char a[ROWS][COLS] = {"foo", "bar", "whatever" };

    for(char(*i)[COLS] = a; i != a+ROWS; ++i)
        swap_char_arrays(i,
                         std::min_element(i, a+ROWS, char_array_less<COLS>));

    for(int i=0; i<ROWS; ++i)
        std::cout << a[i] << '\n';
}

test run: https://ideone.com/15hRB

Upvotes: 2

Mark B
Mark B

Reputation: 96281

That code actually looks suspiciously like C code, not C++ which would use std::string.

There's no way to write an operator< that will work with std::sort because there's no swap that will work right unless you write that TOO.

Using std::string would make this pretty trivial, otherwise you'll have to write your own operator< (look at the C function strcmp) and swap functions.

EDIT: Note that swapping std::strings will almost certainly be faster than swapping huge swaths of memory in a char array.

Upvotes: 4

karlphillip
karlphillip

Reputation: 93458

It's not possible to write an operator< to work with char arrays.

Upvotes: 3

Related Questions