#c #vector #boolean #stdvector
#c #вектор #логическое #stdvector
Вопрос:
Я хочу отсортировать вектор bools по их значению. Это список:
std::vector<bool> bolis {true true false true false false true true};
Есть ли какая-то функция, которая сделала бы этот список равным этому:
{true,true,true,true,true,false,false,false}
Я видел std::sort
функцию, но, похоже, единственное ее реальное применение — сортировать список целых чисел или чисел с плавающей запятой, а не список bools.
Комментарии:
1. Взгляните на
std::partition
.2.
std::sort
конечно, можно было бы использовать. Однако, поскольку существует только два значения, безусловно, существуют более простые решения
Ответ №1:
Первый метод:
Этого можно достичь, определив пользовательскую функцию сравнения и передав ее sort
функции.
Посмотрите на реализацию следующим образом:
#include <iostream>
#include <vector>
#include <algorithm>
//define the function:
bool comparator(bool lhs, bool rhs) { return rhs < lhs; }
int main()
{
std::vector<bool> bolis {true, true, false, true, false, false, true, true};
// pass it to sort:
sort(bolis.begin(), bolis.end(), amp;comparator);
for(int i=0;i<bolis.size();i ){
std::cout<<(bolis[i] ? "true " : "false ");
}
std::cout<<std::endl;
}
Вывод:
true true true true true false false false
Второй метод за O (N) временной сложности:
Подсчитайте количество истинных и ложных значений в векторе и выведите их соответствующим образом.
Например, если имеется 5 истинных значений и 2 ложных значения, затем выведите true для 5 количество раз и false для 2 количество раз.
Или вы также можете поместить значения в другой вектор или отредактировать исходный вектор.
Спасибо @john за все предложения по улучшению ответа!
Комментарии:
1. Спасибо @John. Изменил его.
2. Нет проблем. Мне нравится упоминание O (N) в вашем ответе. Очевидно, что вектор bools может быть отсортирован в O (N) просто путем подсчета, а затем присвоения false или true в соответствующих местах.
3. Спасибо @John! Также добавлено ваше предложение о редактировании исходного вектора.
4.
comparator
не требуется (значение по умолчанию правильное).
Ответ №2:
Сортировка a std::vector<bool>
— это очень специфический случай, и его можно выполнить с помощью очень специфического решения:
подсчет количества true
элементов, а затем перезапись вектора на основе этого количества.
Пример кода:
#include <vector>
#include <iostream>
int main()
{
std::vector<bool> bolis {true, true, false, true, false, false, true, true};
// count number of true
size_t nT = 0;
for (bool value : bolis) nT = value == true;
// write sorted vector
for (size_t i = 0, n = bolis.size(); i < n; i) bolis[i] = i < nT;
// show result
const char *sep = "";
for (bool value : bolis) {
std::cout << sep << std::boolalpha << value;
sep = ", ";
}
}
Вывод:
true, true, true, true, true, false, false, false
Ответ №3:
std::partition
Функция из стандартной библиотеки предназначена для выполнения именно того, что вы хотите сделать. Он принимает диапазон и предикат и переупорядочивает элементы диапазона так, чтобы они были разделены в соответствии с этим предикатом:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<bool> bolis {true, true, false, true, false, false, true, true};
//reorder so that true comes first
std::partition(bolis.begin(), bolis.end(), [](bool b){return b;});
std::cout << std::boolalpha;
std::copy(bolis.begin(), bolis.end(), std::ostream_iterator<bool>(std::cout, " " ));
return 0;
}
Вывод:
true true true true true false false false
Вот демонстрация.