Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- //тут мы будем сортировать массив строк по цифре, которая стоит на месте digit_pos
- void count_sort(std::vector<std::string>& arr, int digit_pos) {
- //число различиных цифр == 10 {0, 1, 2, ..., 9}
- const int DIFFERENT_DIGITS_COUNT = 10;
- //Создаем вектор для сортировки подсчетом. Размер - 10, изначально в каждой ячейке - 0
- std::vector<int> counting(DIFFERENT_DIGITS_COUNT, 0);
- //создали лямбду, которая будет выдергивать цифру из позиции digit_pos. Ее спокойно можно заменить функцией!
- auto get_digit = [digit_pos] (const std::string& number) {
- return number[digit_pos] - '0';
- };
- //прохожусь по всем числам массива и из каждого выдергиваю цифру из digit_pos
- for (const std::string& number : arr) {
- int digit = get_digit(number);
- counting[digit]++;
- }
- /*
- переделываю вектор в котором хранится сколько каких у меня цифр в массив префиксных сумм
- что это дает? это хитрое место.
- например у нас был такой вектор после подсчета
- 0 1 2 3 4 5 6 7 8 9
- {0, 1, 0, 1, 0, 0, 0, 2, 0, 0}
- т.е. мы насчитали одну цифру "1", еще одну "3" и две "7"
- после того, как переделали вектор с подсчетом числа цифр в вектор префиксных сумм - получили
- {0, 1, 1, 2, 2, 2, 2, 4, 4, 4};
- тут я долго осознавал, что нам это дает!
- Дальше я беру из вектора arr число, смотрю на его цифру из разряда с которым работаем.
- Пусть там цифра 7. Дальше я захожу в 7ую ячейку вектора префиксных сумм, вижу число 4 и - магия!
- Кладу число из arr в 4ую(если нумерация от 1) ячейку вектора tmp. 4 - это тот индекс в массиве tmp, куда я должен положить число из arr.
- После этого уменьшаю число из вектора с префиксными суммами на 1.
- {0, 1, 1, 2, 2, 2, 2, 3, 4, 4};
- Там теперь будет лежать число 3. Это значит, что когда я достану из вектора arr числоу которого в разряде с которым я работаю
- будет снова 7 - я ее положу в 3ью ячейку вектора tmp. итд
- */
- for (int i = 1; i < counting.size(); ++i) {
- counting[i] += counting[i - 1];
- }
- //Создаем временный вектор в котором будем хранить результат сортировки
- std::vector<std::string> tmp(arr.size());
- //в цикле иду по нему и расставляю элементы на места
- //причем иду с конца arr, потому что в конце у меня (по смыслу сортировки) лежат большие числа, если рассматривать их предыдущие разряды.
- //Они лежат в определенном порядке, отсортированные по цифре из предыдущего разряда.
- for (int i = arr.size() - 1; i >= 0; --i) {
- int digit = get_digit(arr[i]);
- tmp[counting[digit] - 1] = arr[i];
- counting[digit]--;
- }
- //сохраняю в arr отсортированный вектор tmp
- arr = tmp;
- }
- /*
- Идея сортировки в том, что мы можем сортировать числа - "по цифрам".
- Например есть два числа 132 и 123
- Сначала мы рассмотрим последние цифры - 2 и 3.
- Отсортируем по этоим цифрам, получится - 132, потом 123
- Дальше рассмотрим вторую цифру числа, там 3 и 2.
- Отсортируем по этоим цифрам, получится 123, 132
- Дальше рассмотрим первую цифру - они одинаковые, поэтому не меняем прошлый порядок(!иначе все испортим), оставляем 123, 132
- */
- void radix_sort(std::vector<std::string>& arr) {
- if (arr.empty()) {
- return;
- }
- //цикл идет по числу цифр в числе, начиная с последней (отвечающей за единицы) цифры.
- const int digits_count = arr.front().size();
- for (int digit_pos = digits_count - 1; digit_pos >= 0; --digit_pos) {
- //тут мы с помощью сортировки подсчетом будем сортировать числа по каждой цифре начиная с последней (отвечающей за единицы)
- count_sort(arr, digit_pos);
- }
- }
- int main() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- size_t n;
- std::cin >> n;
- std::vector<std::string> lines(n);
- for (auto& line : lines) {
- std::cin >> line;
- }
- std::cout << std::endl;
- radix_sort(lines);
- for (const auto& line : lines) {
- std::cout << line << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement