Напишите программу, которая находит в списке всех абонентов с заданной фамилией при помощи интервальных алгоритмов lower_bound, upper_bound и equal_range. Отсортируйте список по фамилии (первичный ключ) и имени (вторичный ключ). Предполагается, что имена и номера телефонов читаются из файла следующего формата:
John Doe 345 9483
Nick Bonham 349 2930
Jane Doe 283 2819
Потерялся что за первичный ключ, что за вторичный ключ?
Я так понимаю, что перед применением алгоритмов lower_bound, upper_bound, equal_range нужно массив отсортировать, я прав?
Я такую функцию сравнения создал для сортировки:
int LessThatLastName(const Data_about_a_people& l, const Data_about_a_people& r)
{
return (l.lastName.compare(r.lastName)) - (l.firstName.compare(r.firstName));
/*if ((l.lastName.compare(r.lastName)) < 0)
{
if((l.firstName.compare(r.firstName)) < 0)
return true;
}
return false;*/
}
Если задать отдельно по именам или по фамилиям то сортирует, а вот как составить условие с первичным и вторичным ключами, не знаю. Хотя бы с чем это едят?!)
C/C++
Алгоритмы STL, sort, первичный и вторичный ключи для сортировки.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <set>
#include <sstream>
using namespace std;
struct Abonent {
int code;
int number;
string name;
string surname;
Abonent() : code(0), number(0) {}
private:
friend bool operator<(const Abonent& a, const Abonent& b) {
if (a.surname < b.surname) return true;
if (a.surname == b.surname && a.name < b.name) return true;
return false;
}
friend bool operator==(const Abonent& a, const Abonent& b) {
return a.surname == b.surname && a.name == b.name;
}
friend bool operator!=(const Abonent& a, const Abonent& b) {
return !(a == b);
}
friend bool operator<=(const Abonent& a, const Abonent& b) {
return a < b || a == b;
}
friend bool operator>(const Abonent& a, const Abonent& b) {
return !(a <= b);
}
friend bool operator>=(const Abonent& a, const Abonent& b) {
return !(a < b);
}
friend istream& operator>>(istream& inp, Abonent& a) {
return inp >> a.name >> a.surname >> a.code >> a.number;
}
friend ostream& operator<<(ostream& out, const Abonent& a) {
return out << a.surname << ' ' << a.name << ' ' << a.code << ' ' << a.number;
}
};
class PhoneBook {
public:
bool load(const string& db_path) {
ifstream db(db_path);
if (db.is_open()) {
string record;
Abonent abonent;
while (getline(db, record)) {
istringstream iss(record);
iss >> abonent;
book.insert(abonent);
}
db.close();
return true;
}
return false;
}
multiset<Abonent> get()const {
return book;
}
private:
multiset<Abonent> book;
};
int main() {
cout << "Path: ";
string path;
getline(cin, path);
PhoneBook pb;
if (pb.load(path)) {
auto book = pb.get();
for (const auto& rec : book) cout << rec << '\n';
// TODO:
} else {
puts("Error path!");
}
system("pause > nul");
}
P.S. Вводите путь к файлу базы данных. И если он существует, получаете отсортированный список абонентов. Причём, дубликаты имеют право на существование. Приступайте к поиску. Удачи вам на этом нелёгком пути.
#include <iomanip>
#include <string>
#include <fstream>
#include <set>
#include <sstream>
using namespace std;
struct Abonent {
int code;
int number;
string name;
string surname;
Abonent() : code(0), number(0) {}
private:
friend bool operator<(const Abonent& a, const Abonent& b) {
if (a.surname < b.surname) return true;
if (a.surname == b.surname && a.name < b.name) return true;
return false;
}
friend bool operator==(const Abonent& a, const Abonent& b) {
return a.surname == b.surname && a.name == b.name;
}
friend bool operator!=(const Abonent& a, const Abonent& b) {
return !(a == b);
}
friend bool operator<=(const Abonent& a, const Abonent& b) {
return a < b || a == b;
}
friend bool operator>(const Abonent& a, const Abonent& b) {
return !(a <= b);
}
friend bool operator>=(const Abonent& a, const Abonent& b) {
return !(a < b);
}
friend istream& operator>>(istream& inp, Abonent& a) {
return inp >> a.name >> a.surname >> a.code >> a.number;
}
friend ostream& operator<<(ostream& out, const Abonent& a) {
return out << a.surname << ' ' << a.name << ' ' << a.code << ' ' << a.number;
}
};
class PhoneBook {
public:
bool load(const string& db_path) {
ifstream db(db_path);
if (db.is_open()) {
string record;
Abonent abonent;
while (getline(db, record)) {
istringstream iss(record);
iss >> abonent;
book.insert(abonent);
}
db.close();
return true;
}
return false;
}
multiset<Abonent> get()const {
return book;
}
private:
multiset<Abonent> book;
};
int main() {
cout << "Path: ";
string path;
getline(cin, path);
PhoneBook pb;
if (pb.load(path)) {
auto book = pb.get();
for (const auto& rec : book) cout << rec << '\n';
// TODO:
} else {
puts("Error path!");
}
system("pause > nul");
}
P.S. Вводите путь к файлу базы данных. И если он существует, получаете отсортированный список абонентов. Причём, дубликаты имеют право на существование. Приступайте к поиску. Удачи вам на этом нелёгком пути.
В сортировке используй свою функцию сравнения: если фамилии не равны, то с меньшей будет меньшим, а если равны, то меньшим будет с меньшим именем. Массивы, кстати, функцией sort тоже сортируются.
Андрей Седельников
Это я написал.
int LessThatLastName(const Data_about_a_people& l, const Data_about_a_people& r)
{
if ((l.lastName.compare(r.lastName)) < 0)
{
//if((l.firstName.compare(r.firstName)) < 0)
return true;
}
else if ((l.lastName.compare(r.lastName)) == 0)
{
if ((l.firstName.compare(r.firstName)) < 0)
return true;
}
return false;
}
Теперь другая проблема. А что, если алгоритм lower_bound(), upper_bound() выходят за пределы допустимого диапазона, просто, если показывает на указатель, который является последним элементом. Проверять на выход за пределы допустимого диапазона:
if (low == base.end())
{
cerr << "Out of range low" << endl;
}
int LessThatLastName(const Data_about_a_people& l, const Data_about_a_people& r)
{
if ((l.lastName.compare(r.lastName)) < 0)
{
//if((l.firstName.compare(r.firstName)) < 0)
return true;
}
else if ((l.lastName.compare(r.lastName)) == 0)
{
if ((l.firstName.compare(r.firstName)) < 0)
return true;
}
return false;
}
Теперь другая проблема. А что, если алгоритм lower_bound(), upper_bound() выходят за пределы допустимого диапазона, просто, если показывает на указатель, который является последним элементом. Проверять на выход за пределы допустимого диапазона:
if (low == base.end())
{
cerr << "Out of range low" << endl;
}
Андрей Седельников
И ещё по алгоритму equal_range() у меня выкидывает ошибку, на скрине показал. Что-то не нравится этому алгоритму компаратор. Вот кстати он:
bool isEqualLastName(const Data_about_a_people& d, const Data_about_a_people& v)
{
return d.lastName.compare(v.lastName) == 0;
}
bool isEqualLastName(const Data_about_a_people& d, const Data_about_a_people& v)
{
return d.lastName.compare(v.lastName) == 0;
}
"Я так понимаю, что перед применением алгоритмов lower_bound, upper_bound, equal_range нужно массив отсортировать, я прав?"
Ну да, для работы этих алгоритмов нужен отсортированный контейнер. Только вот массив ли это? Для STL это как минимум vector, но vector ли это? Что за "список" такой? Может там вообще какой-нибудь boost::multi_index имели в виду, а мы тут гадай :)
Ну да, для работы этих алгоритмов нужен отсортированный контейнер. Только вот массив ли это? Для STL это как минимум vector, но vector ли это? Что за "список" такой? Может там вообще какой-нибудь boost::multi_index имели в виду, а мы тут гадай :)
Андрей Седельников
Я использую vector. Если тема алгоритмы STL я, думаю, что имеются ввиду алгоритмы STL. Список, такой пример списка дан в книге: имя, фамилия и номер телефона.
Похожие вопросы
- Алгоритмы STL. Решение оформить в виде class c конструктором, принимающим строку
- Алгоритмы. Бинарная сортировка
- Сравнение скорости сортировки выбором и сортировки слиянием (SelectionSort vs MergeSort)
- Почему не существует универсального алгоритма сортировки?
- Выполните сортировку массивов ТРЕМЯ СПОСОБАМИ: методом пузырька, прямого поиска и быстрой сортировкой. С++
- Выполните сортировку массивов ТРЕМЯ СПОСОБАМИ: методом пузырька, прямого поиска и быстрой сортировкой. С++
- Задача на сортировку структур. Язык C++.
- Проблемы с сортировкой массива методом пузырька.
- На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
- КОНТРОЛЬНЫЕ ЗАДАНИЯ ПО СОРТИРОВКЕ МАССИВОВ
Я не пойму, почему этот код, выкидывает ошибку invalid comparator?
Если в векторе base содержаться отсортированные значения данных, которые я привёл в первом посте, а low_up это пара итераторов на vector. Lower_bound() отрабатывает (хотя и выходит за границы последовательности), upper_bound() отрабатывает нормально, а equal_range() не хочет, что не так. Компаратор один и тот же...