/*
某学校举行运动会,学生们按编号(1、2、3…n)进行标识,
现需要按照身高由低到高排列,
对身高相同的人,按体重由轻到重排列,
对于身高体重都相同的人,维持原有的编号顺序关系。
请输出排列后的学生编号
输入描述:
两个序列,每个序列由N个正整数组成,(0<n<=100)。
第一个序列中的数值代表身高,第二个序列中的数值代表体重,
输出描述:
排列结果,每个数据都是原始序列中的学生编号,编号从1开始,
实例一:
输入:
4
100 100 120 130
40 30 60 50
输出:
2134
*/
以下是错误的做法(或者说是可以做但是我能力做不出来的做法)
刚做时也是准备用两个Map来做,一个是身高对用下标一个是体重对应下标。然后在存放的数组中找到身高相等的对象再二者交换,之后把val值对应相应的值。
vector<int>res;
//vector<int>
multimap<int, int>hash_high;
multimap<int, int>hash_weight;
class Solution
{
public:
public:
void fun_Sort() {
sort(res.begin(), res.end());
multimap<int, int>::iterator it1 = hash_high.begin();
multimap<int, int>::iterator it2 = hash_weight.begin();
for (int i = 0; i < res.size(); ++i)
{
it1++;
it2++;
if ( i + 1 < res.size()&&res[i] == res[i+1])
{
if (it2->second> (++it2)->second)//hash_weight.at(i+1) > hash_weight.at(i+2)
{
it2--;
swap();//it1->first, (++it1)->first
it1--;
//int tmp = res[i];
//res[i] = res[i + 1];
//res[i + 1] = tmp;
}
}
}
}
};
int main()
{
Solution s1;
int num, val = 0;
cin >> num;
for (int i = 1; i <= num; i++)
{
cin >> val;
hash_high.insert(pair<int,int>(val,i));
res.push_back(val);
}
for (int i = 1; i <= num; i++)
{
cin >> val;
hash_weight.insert(pair<int, int>(i,val ));
}
s1.fun_Sort();
multimap<int, int>::iterator it= hash_high.begin();
for (it = hash_high.begin(); it != hash_high.end(); it++)
{
cout<< it->first << endl;
}
return 0;
}
输出还可以这么干(额外两种方法)
此题都要配合sort使用:
一:
for (int i = 0; i < result.size(); i++)
{
cout << hash_map.at(result[i]) << " ";//要配合sort使用
}
二:
for (int i = 0; i < result.size(); i++)
{
auto FIND = hash_map.find(result[i]);
cout << FIND->second;
}
做着做着发现两点不能解决的问题:
一是map是重复的元素该怎么办?做到好久才发现有问题。
二是发现可以multimap了,但是交换元素位置时,发现交换map里的元素不可行,swap函数是交换两个容器。。。。。。。。。当然,map也是一样的。。。。。
后来就放弃这种做法了。
正确的方法:
我发现身高和体重都是可以重复的,那么map会失效(亲测),可重map还不太会用也可能解决不 了问题。那么string 或者两个值放一起不就可以有效的放入map中正好还能排序吗?(连排序sort都省了。。。。)
这么做是否可行我还用vecotor<vector> arr测试过,排序首先排序第一个元素,第一个元素相同排序第二个。。所以我才这么做了,后来发现map弄好了都不用排序。
#include <algorithm>
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int main()
{
int num;
vector<vector<int>>result ;
int val;
vector<int>high;
vector<int>weight;
vector<int>tmp;
map<vector<int>, int>hash_map;
cin >> num;
for (int i = 1; i <= num; i++)
{
cin >> val;
high.push_back(val);
}
for (int i = 1; i <=num; i++)
{
cin >> val;
weight.push_back(val);
}
for (int i = 0; i < num; i++)//将两个数据合并到同一个元素集中。
{
tmp.push_back(high[i]);
tmp.push_back(weight[i]);
result.push_back(tmp);
hash_map.insert(pair<vector<int>, int>(tmp, i+1));//插入哈希元素
tmp.clear();
}
map<vector<int>, int>::iterator it = hash_map.begin();
sort(result.begin(), result.end());
for (it = hash_map.begin(); it != hash_map.end(); it++)
{
cout << it->second << endl;//直接打印即可都不用排序了,map自动排。
}
MAP用法
1.插入元素
// 第一种 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
// 第二种 用insert函数插入value_type数据
mapStudent.insert(map<int, string>::value_type(001, "student_one"));
// 第三种 用"array"方式插入
mapStudent[123] = "student_first";
mapStudent[456] = "student_second";
map<string, string> dict;
dict.insert(pair<string, string>("string", "字符串"));//模板类型pair:构造了一个匿名对象插入到map
dict.insert(make_pair("apple", "苹果"));//模板函数make_pair:偷懒了,实际调的是pair
dict.insert({ "left", "左边" });
dict.insert({ "left", "剩余" });
2.删除元素
从map中删除元素的函数是erase(),该函数有如下的三种形式:
m.erase(k);第一种方法删除的是m中键为k的元素,返回的是删除的元素的个数;
m.erase( p );第二种方法删除的是迭代器p指向的元素,返回的是void;
m.erase(b, e);第三种方法删除的是迭代器b和迭代器e范围内的元素,返回void。
3.map大小查询
int nSize = mapStudent.size();
4.map的元素访问
1.数组方式
下标访问,如果访问的键值不存在会和插入工作相同。
map<int ,int> m;
m[1]=111;
m[2]=222;
m[3]=333;
cout<<m[4];
2.at()访问
么有找到会抛出一个异常,比较安全的访问方式。
map<int ,int> m;
m[1]=111;
m[2]=222;
m[3]=333;
cout<<m.at(4);
**3.find(访问)(map,multimap)***********重要
multimap<int ,int> m;
m.insert({1,11});
m.insert({1,12});
m.insert({1,13});
m.insert({1,14});
m.insert({2,21});
m.insert({3,31});
auto Find=m.find(1);
auto Count=m.count(1);
while(Count)
{
cout<<Find->second<<endl;
Find++;
Count--;
}
此时可以输出所有key=1的 元 素,multimap容器的 元 素添 加方 式不同于map,不能直接用m[key]=value 的 方 式直 接 添加元素,必 须 用insert或者emplace。
multimap不存在operate【】和at().
multimap获取可以获取相同键元素:
4 一种面向迭代器的解决方法lower_bound\upper_bound
```clike
multimap<int ,int> m;
m.insert({1,11});
m.insert({1,12});
m.insert({1,13});
m.insert({1,14});
m.insert({2,21});
m.insert({3,31});
for(auto lo=m.lower_bound(1),hi=m.upper_bound(2);lo!=hi;lo++)
{
cout<<lo->second<<endl;
}
11
12
13
14
21
可以见到,此时不仅可以输出key为1的元素,也能输出key为2的元素。
set和map特性和区别
set是一种关联式容器,其特性如下:
set以RBTree作为底层容器
所得元素的只有key没有value,value就是key
不允许出现键值重复
所有的元素都会被自动排序
不能通过迭代器来改变set的值,因为set的值就是键
**********************************************************************888
map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。它的特性如下:
map以RBTree作为底层容器
所有元素都是键+值存在
不允许键重复
所有元素是通过键进行自动排序的
map的键是不能修改的,但是其键对应的值是可以修改的