555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
1

Сортировка map по значению int в порядке убывания и частично по ключу char :)

07.03.2015, 08:16. Показов 10442. Ответов 35
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.
Помогите, пожалуйста, отсортировать std::map <char, int> a.

Например, у меня есть такие элементы:

5['a']
5['b']
3['f']
8['k']
5['m']
8['w']
1['z']


Нужно получить следущее:

8['k']
8['w']
5['a']
5['b']
5['m']
3['f']
1['z']


Т. е. сначала map сортируется по значению int в порядке убывания, а затем в алфавитном порядке сортируются ключи char, которые имеют одинаковое int-значение.

P.S. Возможно, что ключи-char сортировать не придётся, если их не задеть во время сортировки равных int-значений.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.03.2015, 08:16
Ответы с готовыми решениями:

Сортировка map по ключу и значению
Всем привет. Я создаю map и добавляю туда элементы: map&lt;int,string&gt; m; m=&quot;a&quot;; m=&quot;c&quot;; m=&quot;b&quot;; ...

Map с поиском как по ключу, так и по значению
Реализовано ли подобное в stl? (или в boost, например) И как в теории выглядит эта реализация?...

Сортировка Map по ключу
Всем привет! Сортирую Map по ключу через List -&gt; Sort -&gt; Comparator Почему для 'e1.getKey()'...

MyDictionary: сортировка по ключу, поиск значения по ключу, поиск ключа по значению
Задан интерфейс ІMyDictionary. Его реализует класс MyDictionary, который позволяет определить...

35
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,237
07.03.2015, 12:07 21
Author24 — интернет-сервис помощи студентам
Dennis Ritchie, http://www.cplusplus.com/refer... =transform
сделайте по аналогии под свою задачу.
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 12:20  [ТС] 22
Цитата Сообщение от S_el Посмотреть сообщение
сделайте по аналогии под свою задачу.
Я бы с радостью, но я не знаю, как правильно это написать для таких сложных конструкций, как у меня (по аналогии):
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
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <utility>
#include <iostream>
#include <algorithm>
 
std::map<char, int> a;
std::vector<std::pair<int, char>> b;
 
/*std::map copyCollection(std::map<char, int> x) {
    return std::map<char, int> x;
}*/
 
int main(void) {
    
    int c;
    unsigned long long sum = 0;
    while ((c = getchar()) != EOF)
        if (isalpha(c)) {
            ++a[tolower(c)];
            ++sum;
        }
    
    //std::transform(a.begin(), a.end(), b.begin(), copyCollection);    
    
    return 0;
}
0
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
07.03.2015, 12:34 23
Скопировать в вектор можно и так:
C++
1
2
3
std::map<char, int> map {{'a',5},{'b',5},{'f',3},{'k',8},{'m',5},{'w',8},{'z',1}};
using pait_t = std::pair<char, int>;
std::vector<pait_t> vec{map.begin(), map.end()};
Добавлено через 1 минуту
А задачу я бы решил как то так:
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
#include <iostream>
#include <map>
#include <set>
#include <utility>
 
template <typename T, typename U>
std::ostream & operator <<(std::ostream& os, const std::map<T, U>& map)
{
   for (const auto& p : map) os << p.first << "[" << p.second << "]\n";
   return os << "\n";
}
 
template <typename T, typename U>
std::ostream & operator <<(std::ostream& os, const std::multiset<T, U>& set)
{
   for (const auto& p : set) os << p.first << "[" << p.second << "]\n";
   return os << "\n";
}
 
int main()
{
   std::map<char, int> map {{'a',5},{'b',5},{'f',3},{'k',8},{'m',5},{'w',8},{'z',1}};
   std::cout << map;
   using pait_t = std::pair<char, int>;
 
   auto val_comp = [](const pait_t& p1, const pait_t& p2) {return p1.second > p2.second;};
   auto key_comp = [](const pait_t& p1, const pait_t& p2) {return p1.first > p2.first;};
   std::multiset<pait_t, decltype(val_comp)> set1{map.begin(), map.end(), val_comp};
   std::multiset<pait_t, decltype(key_comp)> set2{map.begin(), map.end(), key_comp};
   std::cout << set1 << set2;
}
1
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 12:46  [ТС] 24
Цитата Сообщение от DiffEreD Посмотреть сообщение
Скопировать в вектор можно и так:
А как потом его отсортировать по убыванию int'ов? И как потом работать с элементами в цикле?
Цитата Сообщение от DiffEreD Посмотреть сообщение
А задачу я бы решил как то так:
Ну мне ещё далеко до такого кода (хотя не совсем далеко).
0
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
07.03.2015, 12:51 25
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
А как потом его отсортировать по убыванию
Ну, тогда копировать в вектор и сортировать так как нужно по условию:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <typename T>
std::ostream & operator <<(std::ostream& os, const std::vector<T>& set)
{
   for (const auto& p : set) os << p.first << "[" << p.second << "]\n";
   return os << "\n";
}
 
int main()
{
   std::map<char, int> map {{'a',5},{'b',5},{'f',3},{'k',8},{'m',5},{'w',8},{'z',1}};
   using pait_t = std::pair<char, int>;
 
   auto val_comp = [](const pait_t& p1, const pait_t& p2) {return p1.second > p2.second;};
   auto key_comp = [](const pait_t& p1, const pait_t& p2) {return p1.first > p2.first;};
 
   std::vector<pait_t> vec{map.begin(), map.end()};
   std::sort(vec.begin(), vec.end(), val_comp);
   std::cout << vec;
   std::sort(vec.begin(), vec.end(), key_comp);
   std::cout << vec;
 
}
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.03.2015, 12:58 26
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
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
 
int main() {
  std::map<char, int> m{{'a', 5},
                        {'b', 5},
                        {'f', 3},
                        {'k', 8},
                        {'m', 5},
                        {'w', 8},
                        {'a', 8},
                        {'c', 8},
                        {'z', 1}};
 
  std::vector<std::pair<char, int>> v{m.begin(), m.end()};
 
  std::stable_sort(v.begin(), v.end(), [](const auto& l, const auto& r) {
    return l.second > r.second;
  });
 
  for (const auto& item : v) {
    std::cout << item.first << " " << item.second << std::endl;
  }
}
http://ideone.com/8zfXpu
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 13:23  [ТС] 27
Цитата Сообщение от DiffEreD Посмотреть сообщение
Ну, тогда копировать в вектор и сортировать так как нужно по условию:
А этот код реально допилить? Или мой код "дохлый"?
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
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <utility>
#include <iostream>
#include <algorithm>
 
std::map<char, int> a;
std::vector<std::pair<int, char>> b;
 
/*std::map copyCollection(std::map<char, int> x) {
    return std::map<char, int> x;
}*/
 
int main(void) {
    
    int c;
    unsigned long long sum = 0;
    while ((c = getchar()) != EOF)
        if (isalpha(c)) {
            ++a[tolower(c)];
            ++sum;
        }
    
    //std::transform(a.begin(), a.end(), b.begin(), copyCollection);    
    
    return 0;
}
Добавлено через 24 минуты
0x10, а как преобразовать этот код в C++11?
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
#include <map>
#include <cctype>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
 
std::map<char, int> m;
 
int main(void) {
    
    int c;
    unsigned long long sum = 0;
    while ((c = getchar()) != EOF)
        if (isalpha(c)) {
            ++m[tolower(c)];
            ++sum;
        }
    
    std::vector<std::pair<char, int>> v{m.begin(), m.end()};
    
    std::stable_sort(v.begin(), v.end(), [](const auto& l, const auto& r) {
        return l.second > r.second;
    });
    
    for (const auto& item : v)
        printf("%c %.3f\n", item.first, (double) (item.second) / sum);
    
    return 0;
}
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.03.2015, 13:26 28
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
а как преобразовать этот код в C++11?
В 22 строке для аргументов лямбды указать конкретные типы вместо auto.
И глобальные переменные тут не нужны.
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 13:37  [ТС] 29
Цитата Сообщение от 0x10 Посмотреть сообщение
В 22 строке для аргументов лямбды указать конкретные типы вместо auto.
Заменил (всё равно не работает):
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
#include <map>
#include <cctype>
#include <vector>
#include <cstdio>
#include <algorithm>
 
int main(void) {
    
    std::map<char, int> m;
    
    int c;
    unsigned long long sum = 0;
    while ((c = getchar()) != EOF)
        if (isalpha(c)) {
            ++m[tolower(c)];
            ++sum;
        }
    
    std::vector<std::pair<char, int>> v{m.begin(), m.end()};
    
    std::stable_sort(v.begin(), v.end(), [](const char& l, const int& r) {
        return l.second > r.second;
    });
    
    for (auto item : v)
        printf("%c %.3f\n", item.first, (double) (item.second) / sum);
    
    return 0;
}
P.S. Нелогичный синтаксис лямбд в C++.
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.03.2015, 13:49 30
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
Заменил (всё равно не работает):
Компаратор принимает два объекта того типа, который хранится в контейнере. Т.е. две пары.
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 13:53  [ТС] 31
Цитата Сообщение от 0x10 Посмотреть сообщение
Т.е. две пары.
И всё равно не работает:
C++
1
std::stable_sort(v.begin(), v.end(), [](std::pair<char, int>> l, std::pair<char, int>> r)
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.03.2015, 14:14 32
Лучший ответ Сообщение было отмечено Dennis Ritchie как решение

Решение

Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
И всё равно не работает:
+ Константные ссылки.
- Лишние символы '>'.
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 14:44  [ТС] 33
Цитата Сообщение от 0x10 Посмотреть сообщение
+ Константные ссылки.
- Лишние символы '>'.
Ну вот, а вы развели кашу на 2 страницы :
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
#include <map>
#include <cctype>
#include <vector>
#include <cstdio>
#include <algorithm>
 
int main(void) {
    
    std::map<char, int> m;
    
    int c;
    unsigned long long sum = 0;
    while ((c = getchar()) != EOF)
        if (isalpha(c)) {
            ++m[tolower(c)];
            ++sum;
        }
    
    std::vector<std::pair<char, int>> v{m.begin(), m.end()};
    
    std::stable_sort(v.begin(), v.end(), [](const std::pair<char, int>& l, const std::pair<char, int>& r) {
        return l.second > r.second;
    });
    
    for (auto item : v)
        printf("%c %.3f\n", item.first, (double) (item.second) / sum);
    
    return 0;
}

Не по теме:

P.S. Вы всех так "выматываете" или только меня?

0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.03.2015, 15:27 34
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
Ну вот, а вы развели кашу на 2 страницы
Решение в посте 26 было почти готовое, с поправкой на стандарт.
Нужно же уметь читать ошибки компилятора, самому следить за синтаксисом и банально понимать что пишется.
0
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
07.03.2015, 15:53  [ТС] 35
Цитата Сообщение от 0x10 Посмотреть сообщение
Нужно же уметь читать ошибки компилятора
Мой косяк: поленился список ошибок до конца пролистать:
Миниатюры
Сортировка map по значению int в порядке убывания и частично по ключу char :)  
0
0 / 0 / 0
Регистрация: 31.07.2020
Сообщений: 1
31.07.2020, 12:02 36
Привет! Так можно реализовать
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 <map>
#include <stdlib.h>
using namespace std;
int main()
{
    string s;
    map<string, int> counters;
    while (cin >> s)
        ++counters[s];
    map<string, int>::const_iterator it = counters.begin();
    while(!counters.empty())
    {
        map<string, int>::const_iterator iterM = counters.begin();
        for (map<string, int>::const_iterator iter = counters.begin(); iter != counters.end(); iter++)
        {
            if (iter->second > iterM->second)
                iterM = iter;
        }
        cout << (*iterM).first << "\t" << (*iterM).second << endl;
        counters.erase(iterM);
    }
    return 0;
}
0
31.07.2020, 12:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.07.2020, 12:02
Помогаю со студенческими работами здесь

Сортировка словаря по ЗНАЧЕНИЮ(не по ключу)
Собственно, как это сделать? Вот мой код: import sys from pprint import pprint #iter_count =...

Как использовать std::map<char,int> в C++/CLI
как использовать std::map&lt;char,int&gt; в С++/CLI при объявление в классе пишит член класса...

Сортировка map по значению
Здорова господа!!! Есть массив: map&lt;string, int&gt; m; m=3; m=2; m=10; Нужно найти...

Сортировка map по значению
Добрый день:) Как можно отсортировать map по возрастанию/убыванию float(неважно ключ это или...

Сортировка map по значению
Доброго времени суток как можно безболезненно отсортировать map по значению? я пробовал bool...

Сортировка map по значению
Есть некий map: map&lt;string, int&gt; MyMap; Нужно вывести на экран всё содержимое контейнера в...


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru