Может ли функция сортировки внутри <algorithm>использоваться для сортировки двумерных массивов символов? - PullRequest
3 голосов
/ 20 марта 2019
char s[251],c[13][21],*p;
int n;
f.get(s,251);
p=strtok(s," ");
n=0;
while(p)
{
    strcpy(c[n],p);
    ++n;
    p=strtok(NULL," ");
}

Код принимает несколько слов, разделенных пробелами, затем слово n помещается в строку n-1 матрицы символов "c". Далее программа должна отсортировать эти слова в алфавитном порядке.

Как я могу использовать функцию "сортировки", чтобы сделать это? Если нет, то есть ли другие способы сделать это?

Ответы [ 3 ]

4 голосов
/ 20 марта 2019

Нет.std::sort нельзя использовать для сортировки двумерного массива, поскольку элементы двумерного массива являются массивами, а массивы нельзя заменять, чего требует std::sort.

Вы можете использовать std::array, как показано Тед , что может быть хорошо для небольшого массива, как у вас.Но имейте в виду, что замена массива имеет линейную сложность, и поэтому сортировка элементов массива может быть довольно медленной для больших массивов.

Если вы хотите отсортировать массив массивов, лучше использовать косвенное обращение.Вместо подмассивов используйте ссылки на массивы.Я имею в виду ссылку в общем смысле;вы не можете иметь массивы T& ссылок.Вы можете оставить свой 2D-массив нетронутым, но отсортируйте массив указателей на этот 2D-массив:

char* rows[std::size(c)];
for(size_t i = 0; i < std::size(c); i++)
    rows[i] = c[i];
}
std::sort(std::begin(rows), std::end(rows), [](char* l, char* r){
    return std::strcmp(l, r) < 0;
});
// rows now contains pointers to each row of c; in sorted order

Если вы хотите изменить исходный массив вместо «представления указателя», вам следует использовать косвенное обращениев самом оригинальном массиве.Для этого вам нужно динамическое распределение, и самое простое решение - std::string:

std::array<std::string, 13> c;

Это можно отсортировать даже без специального объекта сравнения.Обратите внимание, что строки в массиве пусты, поэтому вы должны сначала увеличить их, например, вставив символы.Это не полная замена массива, элементы которого существуют в течение всего времени жизни массива.

4 голосов
/ 20 марта 2019

Нет, вы не можете std::sort char[][] с, потому что массивы не могут быть назначены.Вы можете сортировать char*[] s, потому что указатели имеют вид.

Однако я предлагаю вместо char[][] использовать std::vector<std::string> и сортировать его, или использовать std::set<std::string>, который навязывает алфавитный порядок для его элементов.

std::string line;
f.getline(line);
std::stringstream ss(line);
std::vector<std::string> words(std::istream_iterator<std::string>(ss), {});
std::sort(std::begin(words), std::end(words));
1 голос
/ 20 марта 2019

Как уже ответили, нет, вы не можете. Однако вы можете использовать std::array, где std::sort проведет лексикографическое сравнение внутренних массивов.

std::array<std::array<char, 21>, 13> c;
//...
std::sort(c.begin(), c.end());

for(const auto& v : c)
    std::cout << v.data() << "\n";

Обратите внимание, что это очень медленный способ сортировки строк, поскольку внутренние массивы (std::array<char, 21>) будут копироваться, побайтно, когда им нужно поменяться местами. Вместо этого используйте std::vector<std::string>.

...