Сортировка строк в C ++ с использованием оператора < - PullRequest
1 голос
/ 01 апреля 2011

В C ++ указан следующий массив:

char strings[105][105];

Как правильно написать operator< для сортировки строк с использованием функции STL sort и возможно ли это вообще?

Ответы [ 4 ]

4 голосов
/ 01 апреля 2011

Этот код на самом деле выглядит подозрительно, как код C, а не C ++, который будет использовать std::string.

. Нет способа написать operator<, который будет работать с std::sort, потому что нет никакого свопа, который будет работатьПравильно, если вы не напишите этот TOO.

Использование std::string сделает это довольно тривиальным, иначе вам придется написать свои собственные operator< (посмотрите на функцию C strcmp) и swap функции.

РЕДАКТИРОВАТЬ: обратите внимание, что обмен std::string s почти наверняка будет быстрее, чем обмен огромных участков памяти в массиве char.

3 голосов
/ 01 апреля 2011

Невозможно написать operator< для работы с char массивами.

2 голосов
/ 01 апреля 2011

Предполагая, что вам действительно нужно сортировать двумерный массив по строкам, немного сложно заставить std::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';
}

тестовый прогон: https://ideone.com/15hRB

1 голос
/ 01 апреля 2011

Вы не можете перегружать operator< для указателей, но вам это не нужно, поскольку std :: sort может принимать любую функцию сравнения (или функтор).

Другая проблема заключается в том, что алгоритм сортировкине может поменять массивы, потому что они не могут быть назначены.Но вы можете отсортировать массив указателей в двумерный массив (оставив исходный массив таким, какой он есть).

#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]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...