Как уже отмечали другие, лексикографическая сортировка и объединение близки, но не совсем корректны. Например, для чисел 5
, 54
и 56
лексикографическая сортировка выдаст {5, 54, 56} (в порядке возрастания) или {56, 54, 5} (в порядке убывания), но мы действительно хотим, чтобы это было {56, 5, 54} , поскольку при этом получается максимально возможное число.
Итак, нам нужен компаратор для двух чисел, который каким-то образом ставит сначала самые большие цифры.
- Мы можем сделать это, сравнивая отдельные цифры двух чисел, но мы должны быть осторожны, когда мы сходим с конца одного числа, если другое число все еще имеет оставшиеся цифры. Есть много счетчиков, арифметических и краевых падежей, которые мы должны получить правильно.
Более симпатичное решение (также упоминаемое @Sarp Centel) достигает того же результата, что и (1), но с гораздо меньшим количеством кода. Идея состоит в том, чтобы сравнить конкатенацию двух чисел с обратной конкатенацией этих чисел . Все то, что мы должны явно обработать в (1), обрабатывается неявно.
Например, для сравнения 56
и 5
мы бы регулярно проводили лексикографическое сравнение от 565
до 556
. Поскольку 565
> 556
, мы будем говорить, что 56
"больше", чем 5
, и должно стоять на первом месте. Аналогично, сравнение 54
и 5
означает, что мы протестируем 545
<<code>554, что говорит о том, что 5
"больше", чем 54
.
Вот простой пример:
// C++0x: compile with g++ -std=c++0x <filename>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
int main() {
std::vector<std::string> v = {
"95", "96", "9", "54", "56", "5", "55", "556", "554", "1", "2", "3"
};
std::sort(v.begin(), v.end(),
[](const std::string &lhs, const std::string &rhs) {
// reverse the order of comparison to sort in descending order,
// otherwise we'll get the "big" numbers at the end of the vector
return rhs+lhs < lhs+rhs;
});
for (size_t i = 0; i < v.size(); ++i) {
std::cout << v[i] << ' ';
}
}
При запуске этот код отображает:
9 96 95 56 556 5 55 554 54 3 2 1