Есть структура:
struct data
{
int id;
std::string surname;
std::string name;
std::string patronymic;
std::string post;
double hrPay;
int hours;
};
Есть вектор этих структур:
std::vector<data> m_personal;
Также, имеем функцию выбора метода сортировки вектора и поля сортировки:
char m_sort_choice;
void sortData()
{
std::string myChoice;
char m_sort_choice;
do
{
std::cout << "Sort by:\n";
std::cout << " - ID. Press 1 \n" <<
" - Surname. Press 2 \n" <<
" - Name. Press 3 \n" <<
" - Patronymic. Press 4 \n" <<
" - Post. Press 5 \n" <<
" - Hr. pay. Press 6 \n" <<
" - Hours. Press 7 \n" <<
" - Salary. Press 8 \n" <<
" - Press q to Quit \n" ;
std::cin >> m_sort_choice;
switch (m_sort_choice)
{
case '1': myChoice = "ID"; break;
case '2': myChoice = "Surname"; break;
case '3': myChoice = "Name"; break;
case '4': myChoice = "Patronymic"; break;
case '5': myChoice = "Post"; break;
case '6': myChoice = "Hr. pay"; break;
case '7': myChoice = "Hours"; break;
case '8': myChoice = "Salary"; break;
case 'q': return;
case 'Q': return;
default: m_sort_choice = 'w'; break;
}
} while (m_sort_choice == 'w');
char method;
do
{
std::cout << "Choose method by sort: \n" <<
" - Press 1 to Quick \n" <<
" - Press 2 to Shell \n" <<
" - Press 3 to Bubble \n" <<
" - Press Q to quit \n" ;
std::cin >> method;
switch (method)
{
case '1': std::cout << "Sort by " << myChoice <<
", Method: Quick. \n";
std::sort (m_personal.begin(), m_personal.end(), comp);;
break;
case '2': std::cout << "Sort by " << myChoice <<
", Method: Shell. \n";
sortShell();
break;
case '3': std::cout << "Sort by " << myChoice <<
", Method: Bubble. \n";
sortBubble();
break;
case 'q': return;
case 'Q': return;
default: method = 'w'; break;
}
showAll();
} while (method == 'w');
}
И саму функцию сортировки, которая выглядит так:
void sortBubble()
{
std::vector<data> &arr = m_personal;
for (unsigned int iii = 0; iii < arr.size() - 1; iii++) {
for (unsigned int jjj = 0; jjj < arr.size() - iii - 1; jjj++) {
switch (m_sort_choice)
{
case '1': if (arr.at(jjj).id > arr.at(jjj+1).id)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '2': if (arr.at(jjj).surname > arr.at(jjj+1).surname)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '3': if (arr.at(jjj).name > arr.at(jjj+1).name)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '4': if (arr.at(jjj).patronymic > arr.at(jjj+1).patronymic)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '5': if (arr.at(jjj).post > arr.at(jjj+1).post)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '6': if (arr.at(jjj).hrPay > arr.at(jjj+1).hrPay)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '7': if (arr.at(jjj).hours > arr.at(jjj+1).hours)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
case '8': if (arr.at(jjj).hours * arr.at(jjj).hrPay >
arr.at(jjj+1).hours * arr.at(jjj+1).hours)
{ std::swap(arr.at(jjj), arr.at(jjj+1)); };
continue;
break;
default: break;
}
}
}
}
А хотелось бы её привести примерно к такому виду:
void sortBubble()
{
std::vector<data> &arr = m_personal;
auto x;
switch (m_sort_choice)
{
case '1': x = arr.id; break;
case '2': x = arr.surname; break;
case '3': x = arr.name; break;
case '4': x = arr.patronymic; break;
case '5': x = arr.post; break;
case '6': x = arr.hrPay; break;
case '7': x = arr.hours; break;
case '8': x = arr.hours * arr.hrPay; break;
default: break;
}
for (unsigned int iii = 0; iii < arr.size() - 1; iii++) {
for (unsigned int jjj = 0; jjj < arr.size() - iii - 1; jjj++) {
if (arr.at(jjj).x > arr.at(jjj+1).x)
std::swap(arr.at(jjj), arr.at(jjj+1));
}
}
}
Или:
void sortBubble( std::string myChoice )
{
std::vector<data> &arr = m_personal;
for (unsigned int iii = 0; iii < arr.size() - 1; iii++) {
for (unsigned int jjj = 0; jjj < arr.size() - iii - 1; jjj++) {
if (arr.at(jjj).myChoice > arr.at(jjj+1).myChoice)
std::swap(arr.at(jjj), arr.at(jjj+1));
}
}
}
Есть ли какой-нибудь способ реализовать подобное?
Для этого можно вынести предикат сравнения из функции сортировки:
using Predicate = bool (data const & left, data const & right);
void sortBubble(::std::vector<data> & items, Predicate & predicate)
{
if(::std::size_t{1} < items.size())
{
for(::std::size_t iii{}; iii < items.size() - 1; ++iii)
{
for(::std::size_t jjj{}; jjj < items.size() - iii - 1; ++jjj)
{
if(predicate(items.at(jjj), items.at(jjj + 1)))
{
::std::swap(items.at(jjj), items.at(jjj + 1));
}
}
}
}
}
Predicate * p_predicate{};
switch (m_sort_choice)
{
case '1': p_predicate = [](data const & left, data const & right){ return left.id > right.id ;}; break;
case '2': p_predicate = [](data const & left, data const & right){ return left.surname > right.surname;}; break;
case '3': p_predicate = [](data const & left, data const & right){ return left.name > right.name ;}; break;
...
default: p_predicate = nullptr; break;
}
if(p_predicate)
{
sortBubble(items, *p_predicate);
}
Кроме того, для простых предикатов, сравнивающих по определенному полю, можно написать шаблон использовать его вместо лямбда-выражений:
template<auto x_p_field> bool
gt_field(data const & left, data const & right)
{
return (left.*x_p_field) > (right.*x_p_field);
}
case '1': p_predicate = >_field<&data::id>; break;
case '2': p_predicate = >_field<&data::surname>; break;
Итак, если кому интересно, благодаря пользователю VIT пришёл к следующему решению:
bool comp (const data &a, const data &b)
{
switch (m_sort_choice)
{
case '1': return a.id < b.id;
case '2': return a.surname < b.surname;
case '3': return a.name < b.name;
case '4': return a.patronymic < b.patronymic;
case '5': return a.post < b.post;
case '6': return a.hrPay < b.hrPay;
case '7': return a.hours < b.hours;
case '8': return a.hours * a.hrPay < b.hours * b.hrPay;
default: break;
}
return 0;
}
void sortBubble()
{
std::vector<data> &arr = m_personal;
for (unsigned int iii = 0; iii < arr.size() - 1; iii++) {
for (unsigned int jjj = 0; jjj < arr.size() - iii - 1; jjj++) {
if (comp(arr.at(jjj+1), arr.at(jjj)))
std::swap(arr.at(jjj), arr.at(jjj+1));
}
}
}
Функция comp() у меня используется как компаратор для функции быстрой сортировки, поэтому "странный" порядок аргументов при её вызове.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Могут ли возникнуть проблемы с работой со строками если использовать не char* /const char*, а unsigned char*/const unsigned char*? Если все правильно, к примеру, в UTF-8,...
Имеется форма с двумя выпадающими списками и одной кнопкойПо нажатию на кнопку отправляются данные в виде json, на основе этих данных выполняется...
Как правильно кусок кода засунуть в encodeURIComponent при отправке ajax запроса?