Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/75: Рейтинг темы: голосов - 75, средняя оценка - 4.72
2 / 2 / 0
Регистрация: 12.04.2017
Сообщений: 33

Быстрый поиск в векторе из pair

18.04.2017, 14:54. Показов 16426. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь сделать вектор:
C++
1
vector< pair<string, string> > myVect;
По идее, проще воспользоваться чем-то вроде map или unordered_map, но значения должны сортироваться в том порядке, в котором они были добавлены. Как проще реализовать поиск пары по первому значению pair (аналогично поиску по ключу в map)? Можно наворотить циклов, но, возможно, есть вариант проще и быстрее? Или мою задачу можно решить средствами map?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.04.2017, 14:54
Ответы с готовыми решениями:

Реализовать пользовательский класс Pair (упрощённый аналог std::pair)
Здравствуйте. Проблема с выводом. В приложенном задании, требуется сделать вывод как в примере. Мой вывод основан на вводе количества...

Как в vector<pair <класс, int> > добавлять свой объект в качестве первого элемента pair?
#include&lt;iostream&gt; #include &quot;Employee.h&quot; #include&lt;string&gt; #include&lt;algorithm&gt; #include&lt;vector&gt; #include&lt;list&gt; #include &lt;map&gt; ...

Поиск в векторе
List&lt;Rest&gt; listrest = new List&lt;Rest&gt;(5); Log logs = new Log; Rest fff = new Rest(); fff.Name =...

19
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
18.04.2017, 15:06
http://en.cppreference.com/w/cpp/algorithm/find
не уверен правда, что это то что нужно
map позволяет обращаться и по индексу и по ключу
1
2 / 2 / 0
Регистрация: 12.04.2017
Сообщений: 33
18.04.2017, 15:30  [ТС]
В моём случае всё немного сложнее, у меня нужно найти pair, но известен лишь первый элемент.
0
Эксперт С++
1624 / 954 / 782
Регистрация: 06.02.2016
Сообщений: 2,452
Записей в блоге: 31
18.04.2017, 16:41
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    vector<pair<string,string>>v{{"1","2"},{"3","4"},{"5","6"}};
    auto pp=find_if(v.cbegin(),v.cend(),[](const pair<string,string>&p){
        return p.first=="3";
    });
    cout<<pp->first<<" "<<pp->second<<endl;
    return 0;
}
Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    vector<pair<string,string>>v{{"1","2"},{"3","4"},{"5","6"}};
    const pair<string,string> pp=*find_if(v.cbegin(),v.cend(),[](const pair<string,string>&p){
        return p.first=="3";
    });
    cout<<pp.first<<" "<<pp.second<<endl;
    return 0;
}
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
18.04.2017, 17:10
Лучший ответ Сообщение было отмечено potustoronnim_v как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <vector>
 
template<typename Iterator, typename T>
Iterator findKeyInMap(Iterator begin, Iterator end, const T & v)
{
  for ( ; begin != end; ++begin)
    if (begin->first == v)
      return begin;
    
  return end;
}
 
int main() {
    std::vector<std::pair<std::string, std::string>> v
    {
        { "asd", "qwe" },
        { "zxc", "fgh" }
    };
 
    auto it = findKeyInMap(v.begin(), v.end(), "zxc");
    
    std::cout << it->second;
}
1
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
18.04.2017, 17:51
как насчет двойного индексирования?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class indx{
    vector<string> ordered;
    map<string,string> sorted;
    void insert(pair<string,string> val){
        ordered.insert(val->first);
        sorted[val->first]=val->second;
    }
    string operator [](int i){
        return sorted[ordered[i]];
    }
    string operator [](string s){
        return sortes[s];
    }
}
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
18.04.2017, 18:30
GbaLog-, можно ещё так:
C++
1
2
3
4
5
6
7
template <typename Iterator, typename T>
Iterator findKeyInMap(Iterator begin, Iterator end, const T & v)
{
    while (begin != end && begin->first != v)
        ++begin;
    return begin;
}
Хотя наверняка, кто-нибудь прибежит да скажет, что по фень шую типы параметров begin и end должны быть разными и даже for each цикл в С++17 поменяли под это правило.

Добавлено через 2 минуты
А лучше даже так:
C++
1
2
const std::string key = "zxc";
auto it = std::find_if(v.cbegin(), v.cend(), [&key](const auto &p) { return p.first == key; });
Добавлено через 38 секунд
А этот вариант уже предложили. Ну это его только красит)
1
2 / 2 / 0
Регистрация: 12.04.2017
Сообщений: 33
18.04.2017, 18:47  [ТС]
Peoples, благодарю, работает. Хотя сначала не совсем понял, как, но в итоге разобрался.

GbaLog-, спасибо, все работает. Если можно, пару вопросов по реализации:

1. Почему в 4 строке строка тоже в темплейте? Вроде работает и без него. Также, в 5 строке - const T & v - почему не просто string v?
2. В 7 строке - for ( ; begin != end; ++begin) - почему пропущено объявление итератора? Каким образом он подставляется?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
18.04.2017, 18:49
Цитата Сообщение от potustoronnim_v Посмотреть сообщение
Почему
Чтобы сделать алгоритм универсальным и не зависеть от конкретных типов. Везде, где требуется что-то общее стоит подумать о шаблоне.
1
2 / 2 / 0
Регистрация: 12.04.2017
Сообщений: 33
18.04.2017, 18:55  [ТС]
vndtta, благодарю за ответ, но не совсем понял идею, да и GCC что-то не хочет собирать.

Добавлено через 6 минут
MrGluck, спасибо за ответ. Ещё один глупый вопрос - что меняет в этом случае - const T & v - наличие & ?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
18.04.2017, 19:01
potustoronnim_v, передаём объект по ссылке, иначе создалась бы временная копия (если не рассматривать потенциальную оптимизацию).
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
18.04.2017, 19:11
Цитата Сообщение от potustoronnim_v Посмотреть сообщение
Почему в 4 строке строка тоже в темплейте?
это обобщенная реализация, если вы вдруг решите поменять тип std::string на boost::string_ref, то всё будет работать нормально, в случае с явным указанием типа будет ошибка компиляции.
Цитата Сообщение от potustoronnim_v Посмотреть сообщение
В 7 строке - for ( ; begin != end; ++begin) - почему пропущено объявление итератора?
потому что он передаётся как параметр в функцию.
Цитата Сообщение от potustoronnim_v Посмотреть сообщение
Каким образом он подставляется?
из параметра функции.
Цитата Сообщение от MrGluck Посмотреть сообщение
можно ещё так
как-то неочевидно, имхо.
Цитата Сообщение от MrGluck Посмотреть сообщение
кто-нибудь
я и сам об этом думал, когда писал, но мне чет лень стало.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
18.04.2017, 19:24
Как вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
void print_pair(const pair<string, string> &pr){
cout<<pr.first<<'\t'<<pr.second<<endl;
cout<<"______________________\n";
}
bool less_pair(const pair<string, string> &rhs, const pair<string, string> &lhs){
return rhs.first < lhs.first;
}
int main(int argc, char* argv[])
{
//если вектор, то видимо изменение содержимого достаточно редко или не требуется после заполнения
//тогда имеет смысл использовать преимущество бинарного поиска в упорядоченном векторе
//а при необходимости вставки (если редко нужно), то чтобы не сортировать повторно, место вставки можно искать
//также
    string str_keys[]={"fgkhj","aa", "ngdf", "sds", "er"};
    string str_vals[]={"dfg","rwe", "df", "ert", "mbv"};
    size_t sz=sizeof(str_keys)/sizeof(str_keys[0]);
    vector<pair<string, string>> vecStrPairs;
    for(size_t i=0; i<sz; ++i){
vecStrPairs.push_back(make_pair<string,string>(str_keys[i], str_vals[i]));
    }
sort(vecStrPairs.begin(), vecStrPairs.end(), less_pair);
for(size_t i=0; i<sz; ++i){
pair<string,string> pr= make_pair<string,string>(str_keys[i], str_vals[i]);
vector<pair<string, string>>::iterator fnd_it= lower_bound(vecStrPairs.begin(), vecStrPairs.end(), pr, less_pair);
    if(fnd_it!=vecStrPairs.end()){
cout<<"found"<<endl;
print_pair(*fnd_it);
    }else{
cout<<"not found"<<endl;
print_pair(pr);
    }
}
 
cout<<endl;
system("pause");
return 0;
}
1
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
19.04.2017, 11:57
Цитата Сообщение от potustoronnim_v Посмотреть сообщение
vndtta, благодарю за ответ, но не совсем понял идею, да и GCC что-то не хочет собирать.

Добавлено через 6 минут
MrGluck, спасибо за ответ. Ещё один глупый вопрос - что меняет в этом случае - const T & v - наличие & ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <iterator>
 
using namespace std;
 
typedef class indexer{
    vector<string> _ord;
    map<string,string> _srt;
public:
    indexer():_ord(),_srt(){};
    void push_back(pair<string,string> p){
        _ord.push_back(p.first);
        _srt.insert(p);
    }
    string operator[](int ix){
        return _srt[_ord[ix]];
    }
    string operator[](string key){
        return _srt[key];
    }
    size_t size(){
        return _ord.size();
    }
    map<string,string>::iterator begin(){ return _srt.begin();}
    map<string,string>::iterator end(){ return _srt.end();}
} indexer;
 
int main()
{
    indexer idx;
    idx.push_back(pair<string,string>("this","1"));
    idx.push_back(pair<string,string>("is","2"));
    idx.push_back(pair<string,string>("it","3"));
    for(size_t i=0;i<idx.size();i++)
        cout<<idx[i]<<" "; cout<<endl;
    for(auto x:idx)
        cout<<x.first<<" "<<x.second<<" "<<idx[x.first]<<endl;
}
идея такова, можно обращаться и по индексу и по ключу
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
19.04.2017, 11:59
Цитата Сообщение от vndtta Посмотреть сообщение
идея такова, можно обращаться и по индексу и по ключу
Тогда лучше заюзать интрузивный контейнер из буста.
1
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
19.04.2017, 13:17
Цитата Сообщение от Croessmah Посмотреть сообщение
Тогда лучше заюзать интрузивный контейнер из буста.
интрузивный не интрузивный, что удобней то и используй
примерчик лучше сразу
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
19.04.2017, 13:19
Цитата Сообщение от vndtta Посмотреть сообщение
интрузивный не интрузивный, что удобней то и используй
примерчик лучше сразу
Он имеет в виду boost bimap
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
19.04.2017, 13:30
MrGluck, нет, я имел ввиду
не владеющий контейнер boost::intrusive_set.
Про bimap что-то даже и не вспоминал.
0
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
19.04.2017, 13:31
Цитата Сообщение от MrGluck Посмотреть сообщение
Он имеет в виду boost bimap
сомневаюсь, там X<->Y, а тс нужен как я понял K->Y,X->Y где K - ключ строка, а X - номер в порядке добавления
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
19.04.2017, 13:52
Цитата Сообщение от vndtta Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class indx{
    vector<string> ordered;
    map<string,string> sorted;
    void insert(pair<string,string> val){
        ordered.insert(val->first);
        sorted[val->first]=val->second;
    }
    string operator [](int i){
        return sorted[ordered[i]];
    }
    string operator [](string s){
        return sortes[s];
    }
}
Такие решение могут нарушать инвариант класса, т.е. вводить объект в некосистентное состояние. Лучше заюзать какой-нибудь boost::multi_index, который может хранить объекты в порядке вставки при это предоставляет доступ по ключам.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.04.2017, 13:52
Помогаю со студенческими работами здесь

Поиск в векторе
Есть вектор v: v = 0; v = 1; v = 2; v = 4; v = 6; Как с помощью алгоритма find узнать есть ли в векторе число 8, между...

Поиск в векторе
Есть вектор v Нужно задать поиск значения 6 и присвоить переменной i номер элемента вектора v, в котором найдена искомое значение 6. В...

Поиск в векторе (структура)
Добрый день. Помогите пожалуйста начинающему сишнику))), создать две функции 1. Функция находила бы номер записи, если есть, в векторе...

Поиск и замена в векторе
Есть вектор v, который содержит следующие значения элементов: v Нужно найти и заменить значения 5 на 1, чтобы в итоге получилось: v

Поиск элемента в векторе.
Сформировать программу в mathcad: Если в заданном целочисленном векторе A(N) есть элементы со значением, равным заданному числу B, то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru