基础
sizeof(变量) 求占用字节数
#define MAX 1000
cin.get()是一个int变量
int c;
while ((c = cin.get()) != EOF)
{//用cin读入所有字符,包括空格换行
cout << (char)c;
}
或
char c;
while (scanf("%c", &c) != EOF)
{
printf("%c", c);
}
freopen(“E:\test.txt”, “r”, stdin);以后输入从文件里取
字符处理函数:
这些库函数在ctype中声明:
与或非
&
21: 00010101
18: 00010010
21&18:00010000 相当于是取交集,相同则为一
|:
21: 00010101
18: 00010010
21|18:00010111 相当于取并集
^:
21: 00010101
18: 00010010
21^18:00000111 相同为0,不同为一
~:
21: 00010101
~21: 11101010
9<<4:
00001001
10010000 每左移一位相当于乘2
9>>4:
每右移一位相当于除2
不通过第三个变量能实现交换两个变量的值
int a=5,b=7;
a=a^b;
b=b^a;
a=a^b;
字符串中 char a[2]要增添0的话,需为a[2]= ‘0’,而不是=0
使用cin.getline(char buf[],int bufsize)可避免越界
读入bufsize-1个字符
gets(char buf[]) 完整的读入一行,可能会越界
#include <cstring>
strcat(char []a,char []b);//b接到a后面
strupr(char [])转换为大写
strlwr(char [])转换为小写
遍历字符串操作:
for (int i = 0; a[i]; i++)
{
printf("%c ", a[i]);
}
空指针:int *p=NULL或0但操作系统不允许访问该地址
函数形参:
void Fun( int *p) 或Fun(int p[])
位运算
#include <iostream>
using namespace std;
int main()
{
int a, n;
cin >> a >> n;
a=a >> n;
cout << a << endl;
return 0;
}
字符串操作库函数
char *strchr(const char *str, int c);
寻找字符c在字符串中第一次出现的位置,如果找到返回其指针,不存在则返回NULL
char*strstr(const char*str,const char *substr);
寻找字符substr在str中第一次出现的位置,如果找到则返回该位置指针,不包含则返回NULL
int stricmp(const char *s1,const char *s2);
大小写无关的字符串比较
int strncmp(const char *s1,const char *s2);
比较s1前n个字符组成的子串和s2前n个字符组成的子串大小
char *strncpy(char *dest,const char *src, int n);
拷贝src的前n个字符到dest,如果长度大于n,该函数不会自动填充 ‘\0’
strtok(str, “ ,.-”);
把字符串按照后的符号分开,但仅能取出一个被分割的
strtok尝试
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char a[] = { "hello,ok.nia" };
char* p = a;
p = strtok(a, ",.");
while (p != NULL)
{//p不为空则说明找到了子串
cout << p << endl;
p = strtok(NULL, ",.");//后续调用开头为NULL
}
}
字符串0新认识
#include <iostream>
using namespace std;
int main()
{
char a[10] = {"abcd"};
for (int i = 0; a[i]; i++)
{
printf("%c ", a[i]);
}
return 0;
}
void 指针无定义
voidmemset(voiddest,int ch,int n);
将从dest开始的n个字节都设置成ch
全部设置为0 int a[100];memset(a,0,sizeof(a));
void *memcpy(void dest,voidsrc,int n);
将src开始的n个字节拷贝到地址dest。返回值是dest
函数指针:
void (*pf)(int,int);
pf=Fun;
快排
void qsort(void base,int nelem,unsigned int width,int (pfCompare(const void,const void)));
快排 base为起始地址,nelem为元素个数,width为每一个元素大小,pfCompare比较函数的地址,由程序员自己编写
自己写的函数应该为:
MyCompare(const void*elem1, const void*elem2)
{//函数内部调用需进行强制类型转化
unsigned int*p1,*p2;
p1=(unsigned int*)elem1;
}
结构:
struct 结构名
{
类型名 成员变量名;
类型名 成员变量名;
};
struct Student
{
unsigned ID;
char szName[20];
float fGPA;
};
Student s1,s2;
//也可以结构套结构:
struct Date
{
int year;
int month;
int day;
};
struct StudentEx
{
unsigned ID;
char szName[20];
float fGPA;
Date birthday;
};
初始化为: StudentEx stu={1234, “tom”,3.7,{1900,2,1}};
成员变量可以是指向本结构类型的变量的指针
struct employee
{
string name;
employee *next;
}
变量
-
静态变量:程序运行期间,存放地址不发生改变
-
全局变量都是静态变量,局部变量前增加static也可以变为静态变量
若未进行初始化,则静态变量会被自动初始化为全0,局部非静态变量的值则为随机.
静态变量的初始化语句只进行一次,以后都不会进行void func() { static int n = 4;//此句只执行一次 cout<<n<<endl; ++n; } int main() { func();func();func(); } //结果为4 5 6
char *Strtok(char *p,char *sep) { static char * start;//本次查找的起点 if(p) { start = p; } for(;*start && strchr(sep, *strat); ++start); //此循环跳过了分隔符号 if(*start ==0) { return NULL; } char *q = start; for(;*start && !strchr(sep, *start); ++start); //此循环跳过了非分隔符号 if(*start) { *start = 0; ++start; } return q; }
排序
选择排序,插入排序0(n^2),冒泡排序
- 时间复杂度:
0(n) 0(n^2) 只按最大的次方来算
复杂度有平均复杂度和最坏复杂度,两者可能相同也可不同- 常数复杂度 0(1) 操作次数和问题无关
- 对数复杂度
- 线性复杂度
- 多项式复杂度
- 指数复杂度
- 阶乘复杂度
- 无序数列中查找一个数:0(n)
- 平面上有n个点,找出任意两点间距离 0(n^2)
- 插入排序、选择排序、冒泡排序 0(n^2)
- 快速排序 0(n*log(n)) 快排的最坏复杂度就是0(n^2)是已经排好序的
- 二分查找 0(log(n))
二分查找中中点的位置要写为 mid=L+(R-L)/2
而不是 (L+R)/2
例题:输入n个整数,找出其中两个数,使得之和等于整数m.
解法1:一一对应着去查找,0(n^2)
解法2:先进行快排0(nlog(n))在进行二分查找0(log(n))
解法3:先进行快排0(nlog(n)),a[i]+a[j]如果大于m,j–,小于则i++
Vector
#include <vector>
vector<int> pile[maxn];
vector像是一个二维数组,一维大小固定,二维大小不固定
vector示例
#include <iostream>
#include <vector>
using namespace std;
template<class T>
void PrintVector(T s, T e)
{
for (; s != e; ++s)
cout << *s << " ";
cout << endl;
}
int main()
{
int a[5] = {
1, 2, 3, 4, 5};
vector<int> v(a, a + 5); //将数组a的内容放入v
cout << "1) " << v.end() - v.begin() << endl;
//两个随机迭代器可以相减,输出 1) 5
cout << "2) ";
PrintVector(v.begin(), v.end());
//2) 1 2 3 4 5
v.insert(v.begin() + 2, 13); //在begin()+2位置插入 13
cout << "3) ";
PrintVector(v.begin(), v.end());
//3) 1 2 13 3 4 5
v.erase(v.begin() + 2); //删除位于 begin() + 2的元素
cout << "4) ";
PrintVector(v.begin(), v.end());
//4) 1 2 3 4 5
vector<int> v2(4, 100); //v2 有4个元素,都是100
v2.insert(v2.begin(), v.begin() + 1, v.begin() + 3);
//将v的一段插入v2开头
cout << "5) v2: ";
PrintVector(v2.begin(), v2.end());
//5) v2: 2 3 100 100 100 100
v.erase(v.begin() + 1, v.begin() + 3);
//删除 v 上的一个区间,即 2,3
cout << "6) ";
PrintVector(v.begin(), v.end());
//6) 1 4 5 return 0;
}
用vector实现二维数组
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> v(3);
//v有3个元素,每个元素都是vector<int> 容器
for (int i = 0; i < v.size(); ++i)
{
for (int j = 0; j < 4; ++j)
{
v[i].push_back(j);
}
}
for (int i = 0; i < v.size(); ++i)
{
for (int j = 0; j < v[i].size(); ++j)
{
cout << v[i][j] << " ";
}
cout << endl;
}
return 0;
}
大整数类
无需关注每个整数多大,vector会自动申请内存0
#include <vector>
#include <string>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct BigInteger
{
static const int BASE = 100000000;
static const int WIDTH = 8;
vector<int> s;
BigInteger(long long num = 0)
{//构造函数
*this = num;
}
BigInteger operator=(long long num)
{//赋值运算
s.clear();
do
{
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger operator=(const string &str)
{//赋值运算
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++)
{
int end = str.length() - i * WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start, end - start).c_str(), "%d", &x);
s.push_back(x);
}
return *this;
}
BigInteger operator+(const BigInteger &b) const
{
BigInteger c;
c.s.clear();
for (int i = 0, g = 0;; i++)
{
if (g == 0 && i >= s.size() && i > b.s.size())
{
break;
}
int x = g;
if (i < s.size())
{
x += s[i];
}
if (b.s.size())
{
x += b.s[i];
}
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
BigInteger operator+=(const BigInteger &b)
{
*this = *this + b;
return *this;
}
bool operator<(const BigInteger &b) const
{
if (s.size() != b.s.size())
{
return s.size() < b.s.size();
}
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] != b.s[i])
{
return s[i] < b.s[i];
}
}
return false;
}
};
ostream &operator<<(ostream &out, const BigInteger &x)
{
out << x.s.back();
for (int i = x.s.size() - 2; i >= 0; i--)
{
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for (int j = 0; j < strlen(buf); j++)
{
out << buf[j];
}
}
return out;
}
istream &operator>>(istream &in, BigInteger &x)
{
string s;
if (!(in >> s))
{
return in;
}
x = s;
return in;
}
Deque
双向队列,在两端增删元素具有较佳性能
所有适用于 vector的操作都适用于 deque
List
双向链表,在内存中不连续存放,不支持随机存取
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class A
{
private:
int n;
public:
A(int n_)
{
n = n_; }
friend bool operator<(const A &a1, const A &a2);
friend bool operator==(const A &a1, const A &a2);
friend ostream &operator<<(ostream &o, const A &a);
};
bool operator<(const A &a1, const A &a2)
{
return a1.n < a2.n;
}
bool operator==(const A &a1, const A &a2)
{
return a1.n == a2.n;
}
ostream &operator<<(ostream &o, const A &a)
{
o << a.n;
return o;
}
template<class T>
void PrintList(const list<T> &lst)
{
//不推荐的写法,还是用两个迭代器作为参数更好
int tmp = lst.size();
if (tmp > 0)
{
typename list<T>::const_iterator i;
i = lst.begin();
for (i = lst.begin(); i != lst.end(); i++)
{
cout << *i << ",";
}
}
}
int main()
{
list<A> lst1, lst2;
lst1.push_back(1);
lst1.push_back(3);
lst1.push_back(2);
lst1.push_back(4);
lst1.push_back(2);
lst2.push_back(10);
lst2.push_front(20);
lst2.push_back(30);
lst2.push_back(30);
lst2.push_back(30);
lst2.push_front(40);
lst2.push_back(40);
cout << "1) ";
PrintList(lst1);
cout << endl;
// 1) 1,3,2,4,2,
cout << "2) ";
PrintList(lst2);
// 2) 40,20,10,30,30,30,40, cout << endl;
lst2.sort();
cout << "3) ";
PrintList(lst2);
cout << endl;
//3) 10,20,30,30,30,40,40, lst2.pop_front();
cout << "4) ";
PrintList(lst2);
cout << endl;
//4) 20,30,30,30,40,40,
lst1.remove(2); //删除所有和A(2)相等的元素
cout << "5) ";
PrintList(lst1);
cout << endl;
//5) 1,3,4,
lst2.unique(); //删除所有和前一个元素相等的元素
cout << "6) ";
PrintList(lst2);
cout << endl;
//6) 20,30,40,
lst1.merge(lst2); //合并 lst2到lst1并清空lst2
cout << "7) ";
PrintList(lst1);
cout << endl;
//7) 1,3,4,20,30,40,
cout << "8) ";
PrintList(lst2);
cout << endl;
//8)
lst1.reverse();
cout << "9) ";
PrintList(lst1);
cout << endl;
//9) 40,30,20,4,3,1,
lst2.push_back(100);
lst2.push_back(200);
lst2.push_back(300);
lst2.push_back(400);
list<A>::iterator p1, p2, p3;
p1 = find(lst1.begin(), lst1.end(), 3);
p2 = find(lst2.begin(), lst2.end(), 200);
p3 = find(lst2.begin(), lst2.end(), 400);
lst1.splice(p1, lst2, p2, p3);
//将[p2,p3)插入p1之前,并从lst2中删除[p2,p3)
cout << "10) ";
PrintList(lst1);
cout << endl;
//10) 40,30,20,4,200,300,3,1,
cout << "11) ";
PrintList(lst2);
cout << endl;
//11) 100,400,
return 0;
}
Queue
队列,插入在尾部进行
删除,检索等只能在头部进行
STL算法
#include<algorithm>
用sort进行排序
sort(数组名+n1,数组名+n2);n1省略即为从第一开始
int a[5] = { 9,7,3,8,6 };
sort(a, a+2);从小到大
sort从大到小排序:
sort(数组名+n1,数组名+n2,greater());
T代表基本类型数组 T=int
#include <iostream>
#include <algorithm>
using namespace std;
void print(int a[], int size)
{
for (int i = 0; i < size; i++)
{
cout << a[i] << ",";
}
cout << endl;
}
struct Rule1
{//按从大到小排序
bool operator()(const int& a1, const int& a2)const
{
return a1 > a2;
}
};
struct Rule2
{//按个位数从小到大排序
bool operator()(const int& a1, const int& a2)const
{
return a1 % 10 < a2 % 10;
}
};
int main()
{
int a[] = { 12,45,3,98,21,7 };
sort(a, a + sizeof(a) / sizeof(int));
cout << "1)从小到大: "; print(a, sizeof(a) / sizeof(int));
sort(a, a + sizeof(a) / sizeof(int), Rule1());
cout << "2)从大到小: "; print(a, sizeof(a) / sizeof(int));
sort(a, a + sizeof(a) / sizeof(int), Rule2());
cout << "3)按个位数从小到大: "; print(a, sizeof(a) / sizeof(int));
}
自定义排序规则
sort(数组名+n1,数组名+n2,排序规则结构名());
struct 结构名
{
bool operator()(const T &a1,const T &a2)const
{
//若a1应该在a2前面,则返回true
//否则返回false
}
}
用sort进行排序二
struct Rule1
{//按从大到小排序
bool operator()(const int &a1,const int &a2)const
{
return a1>a2;
}
};
struct Rule2
{//按个位数从小到大排序
bool operator()(const int &a1,const int &a2)const
{
return a1%10 < a2%10;
}
};
用sort进行排序三:对结构进行排序
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct Student
{
char name[20];
int id;
double gpa;
};
Student students[] =
{
{"Jack",112,3.4},
{"Mary",102,3.8},
{"Maryl",117,3.9},
{"Ala",333,3.5},
{"Zero",101,4.0}
};
struct StudentRule1
{//按姓名从小到大排
bool operator()(const Student& s1, const Student& s2)const
{
if (strcmp(s1.name, s2.name) < 0)
{
return true;
}
return false;
}
};
struct StudentRule2
{//按id从小到大排
bool operator()(const Student& s1, const Student& s2)const
{
return s1.id < s2.id;
}
};
struct StudentRule3
{//按gpa从小到大排
bool operator()(const Student& s1, const Student& s2)const
{
return s1.gpa < s2.gpa;
}
};
void PrintStudents(Student s[], int size)
{
for (int i = 0; i < size; ++i)
{
cout << "(" << s[i].name << "'" << s[i].id << ',' << s[i].gpa << ")";
}
cout << endl;
}
int main()
{
int n = sizeof(students) / sizeof(Student);
sort(students, students + n, StudentRule1());
PrintStudents(students, n);
sort(students, students + n, StudentRule2());
PrintStudents(students, n);
sort(students, students + n, StudentRule3());
PrintStudents(students, n);
return 0;
}
STL查找是在排好序的数组上进行二分查找
binary_search进行二分查找
-
方法一:
binary_search(数组名+n1,数组名+n2,值);
返回布尔值
!!!a必须在b前面,b必须在a前面都不成立,不是== -
方法二:
binary_search(数组名+n1,数组名+n2,值,排序规则结构名);
任意类型的规则,返回布尔值
!!!a必须在b前面,b必须在a前面都不成立,不是==#include <iostream> #include <algorithm> using namespace std; struct Rule {//按个位从小到大排 bool operator()(const int& a1, const int& a2) { return a1 % 10 < a2 % 10; } }; void Print(int a[], int size) { for (int i = 0; i < size; i++) { cout << a[i] << ','; } cout << endl; } int main() { int a[] = { 12,45,3,98,21,7 }; sort(a, a + 6); Print(a, 6); cout << "查找12:" << binary_search(a, a + 6, 12) << endl; cout << "查找77:" << binary_search(a, a + 6, 77) << endl; sort(a, a + 6, Rule()); Print(a, 6); cout << "查找7:" << binary_search(a, a + 6, 7) << endl; //按个位排序后的正常查找是没有意义的 cout << "查找8:" << binary_search(a, a + 6, 8, Rule()) << endl; //按原有只排个位数字就有意义了 return 0; }
lower_bound 二分查找下界
- 方法一:
T * lower_bound(数组名+n1,数组名+n2,值)
返回一个指针T *p;
*p是查找区间下标最小的,大于等于“值”的元素,如果找不到则返回指向n2的元素 - 方法二:
T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针T *p;
upper_bound 二分查找下界
-
方法一:
T * lower_bound(数组名+n1,数组名+n2,值)
返回一个指针T *p;
*p是查找区间下标最小的,大于“值”的元素,如果找不到则返回指向n2的元素 -
方法二:
T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针T *p;#include <iostream> #include <cstring> #include <algorithm> using namespace std; struct Rule {//个位数排序 bool operator()(const int& a1, const int& a2) { return a1 % 10 < a2 % 10; } }; void Print(int a[], int size) { for (int i = 0; i < size; ++i) { cout << a[i] << ","; } cout << endl; } #define NUM 7 int main() { int a[NUM] = { 12,5,3,5,98,21,7 }; sort(a, a + NUM); Print(a, NUM); int* p = lower_bound(a, a + NUM, 5); cout << *p << "p-a" << p - a << endl; p = upper_bound(a, a + NUM, 5); cout << *p << endl; cout << *upper_bound(a, a + NUM, 13) << endl; sort(a, a + NUM, Rule()); Print(a, NUM); cout << *lower_bound(a, a + NUM, 16, Rule()) << endl; cout << lower_bound(a, a + NUM, 25, Rule()) - a << endl; cout << upper_bound(a, a + NUM, 18, Rule()) - a << endl; if (upper_bound(a, a + NUM, 18, Rule()) == a + NUM) { cout << "not found" << endl; } cout << *upper_bound(a, a + NUM, 5, Rule()) << endl; cout << *upper_bound(a, a + NUM, 4, Rule()) << endl; return 0; }
STL中的平衡二叉树数据结构
-
需要在大量增加,删除数据的同时,还要进行大量数据的查找
-
希望增加数据,删除数据,产找数据都能在log(n)复杂度完成
-
排序+二分查找显然不可以,因加入新数据就要重新排序
就可以使用“平衡二叉树”数据结构存放数据,体现在STL中,就是以下四种“排序容器”
multiset set multimap map
multiset
multiset <T> st;
定义了一个multiset变量st,st里面可以存放T类型的数据,并且自动排序
排序规则:表达式“a<b”为true
,则a排在b前面
可用st.insert添加元素,st.find查找元素,st.erase删除元素,复杂度都是log(n)
迭代器
multiset<int>::iterator i;
-
i是迭代器,相当于指针,可用于指向multiset中的元素,访问multiset中的元素要通过迭代器
与指针不同:
multiset上迭代器可++,–,用!=和==比较,不可比大小,不可加减整数,不可相减 -
st.begin()返回值类型是
multiset<int>::iterator,
是指向st中的头一个元素的迭代器 -
st.end()返回值类型是
multiset<int>::iterator,
是指向st中的最后一个元素后面的迭代器 -
对迭代器++,其就指向容器中下一个元素,–则令其指向上一个元素
-
st.size()
#include <iostream> #include <cstring> #include <set> using namespace std; int main() { multiset<int> st; int a[10] = { 1,14,12,13,7,13,21,19,8,8 }; for (int i = 0; i < 10; i++) {//插入的是a[i]的复制品 st.insert(a[i]); } //迭代器,类似于指针,这样来遍历数据 multiset<int>::iterator i; for (i = st.begin(); i != st.end(); ++i) { cout << *i << ","; } cout << endl; i = st.find(22);//查找22,返回值是迭代器 if (i == st.end()) {//找不到则返回值为end() cout << "not found" << endl; } st.insert(22);//插入22 i = st.find(22); if (i == st.end()) { cout << "not found" << endl; } else {//找到则返回指向找到的元素的迭代器 cout << "found:" << *i << endl; } i = st.lower_bound(13); //返回最靠后的迭代器it,使得[begin(),it)中的元素都在13前面,复杂度log(n) cout << *i << endl; i = st.upper_bound(13); //返回最靠前的迭代器it,使得[it,end())中的元素都在8前面,复杂度log(n) cout << *i << endl; st.erase(i);//删除迭代器i指向的元素,即12 for (i = st.begin(); i != st.end(); ++i) { cout << *i << ","; } return 0; }
自定义规则的multiset
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
struct Rule1
{
bool operator()(const int& a, const int& b)
{//返回值为true则说明a必须排在b前面
return (a % 10) < (b % 10);
}
};
int main()
{
multiset<int, greater<int>>st;
//排序规则为从大到小
int a[10] = { 1,14,12,13,7,13,21,19,8,8 };
for (int i = 0; i < 10; ++i)
{
st.insert(a[i]);
}
multiset<int, greater<int>>::iterator i;
for (i = st.begin(); i != st.end(); ++i)
{
cout << *i << ",";
}
cout << endl;
multiset<int, Rule1>st2;
//排序规则为个位数小的在前面
for (int i = 0; i < 10; ++i)
{
st2.insert(a[i]);
}
multiset<int, Rule1>::iterator p;
for (p = st2.begin(); p != st2.end(); ++p)
{
cout << *p << ",";
}
cout << endl;
p = st2.find(133);
cout << *p << endl;
return 0;
}
自定义结构的规则的multiset
#include <iostream>
#include <cstring>
#include <set>
#include <cstring>
using namespace std;
struct Student
{
char name[20];
int id;
int score;
};
Student students[] =
{
{"Jack",112,78},
{"Mary",102,85},
{"Ala",333,92},
{"Zero",101,70},
{"Cindy",102,78}
};
struct Rule
{
bool operator()(const Student& a, const Student& b)const
{
if (a.score != b.score)
{
return a.score > b.score;
}
else
{
return strcmp(a.name, b.name) < 0;
}
}
};
int main()
{
multiset<Student, Rule>st;
for (int i = 0; i < 5; ++i)
{//插入的是students[i]
st.insert(students[i]);
}
multiset<Student, Rule>::iterator p;
for (p = st.begin(); p != st.end(); ++p)
{
cout << p->score << " " << p->name << " " << p->id << endl;
}
Student s = { "Mary",1000,85 };
p = st.find(s);
if (p != st.end())
{
cout << p->score << " " << p->name << " " << p->id << endl;
}
return 0;
}
set
set和multiset区别在于容器内不能有重复的元素
set插入元素可能不成功
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
int main()
{
set<int>st;
int a[10] = { 1,2,3,8,7,7,5,6,8,12 };
for (int i = 0; i < 10; i++)
{
st.insert(a[i]);
}
cout << st.size() << endl;
set<int>::iterator i;
for (i = st.begin(); i != st.end(); ++i)
{//只有8个元素
cout << *i << ",";
}
cout << endl;
struct
{
set<int>::iterator first;
bool second;
} result = st.insert(2);
if (! result.second)
{//条件成立说明插入不成功
cout << *result.first << "already exists." << endl;
}
else
{
cout << *result.first << "inserted." << endl;
}
return 0;
}
multimap
multimap容器里的元素,都是pair形式的
multimap<T1,T2> mp;
则mp里元素都是如下类型:
struct
{
T1 first
T2 second;
}
multimap中的元素按照dirst排序,并可以按照first进行查找
缺省的排序规则是 “a.first<b.first”为true,则a排在b前面
typedef multimap<int, StudentInfo> MAP_STD;
此后MAP_STD 等价于multimap<int, StudentInfo>
typedef int * PINT;
此后PINT等价于 int*. 即PINT p;等价于int *p;
#include <iostream>
#include <map>
#include <cstring>
using namespace std;
struct StudentInfo
{
int id;
char name[20];
};
struct Student
{
int score;
StudentInfo info;
};
typedef multimap<int, StudentInfo> MAP_STD;
int main()
{
MAP_STD mp;
Student st;
char cmd[20];
while (cin >> cmd)
{
if (cmd[0] == 'A')
{
cin >> st.info.name >> st.info.id >> st.score;
mp.insert(make_pair(st.score, st.info));
}
//make_pair生成一个pair<int,StudentInfo>变量
//其first等于st.score,second等于st.info
else if (cmd[0] == 'Q')
{
int score;
cin >> score;
MAP_STD::iterator p = mp.lower_bound(score);
if (p != mp.begin())
{
--p;
score = p->first;//比要查询分数低的最高分
MAP_STD::iterator maxp = p;
int maxId = p->second.id;
for (; p != mp.begin() && p->first == score; --p)
{//遍历所有成绩和score相等的学生
if (p->second.id > maxId)
{
maxp = p;
maxId = p->second.id;
}
}
if (p->first == score)
{//如果上面循环是因为p==mp.begin()而终止,
//则p指向的元素还要处理
if (p->second.id > maxId)
{
maxp = p;
maxId = p->second.id;
}
}
cout << maxp->second.name << " "
<< maxp->second.id << " "
<< maxp->first << endl;
}//lower_bound的结果就是begin.说明没任分数比查询分数低
else
{
cout << "Nobody" << endl;
}
}
}
return 0;
}
map
和multimap区别在于:
不能有关键字重复的元素
可以使用[],下标为关键字,返回值为first和关键字相同的元素的second
插入元素可能失败
#include <iostream>
#include <map>
#include <cstring>
using namespace std;
struct Student
{
string name;
int score;
};
Student students[5] =
{
{"Jack",89},
{"Tom",74},
{"Cindy",87},
{"Alysa",87},
{"Micheal",98}
};
typedef map<string, int> MP;
int main()
{
MP mp;
for (int i = 0; i < 5; i++)
{
mp.insert(make_pair(students[i].name, students[i].score));
}
cout << mp["Jack"] << endl;//输出98
mp["Jack"] = 60;//修改名为“Jack”的元素的second
for (MP::iterator i = mp.begin(); i != mp.end(); ++i)
{
cout << "(" << i->first << "," << i->second << ")";
}
cout << endl;
Student st;
st.name = "Jack";
st.score = 99;
pair<MP::iterator, bool> p =
mp.insert(make_pair(st.name, st.score));
if (p.second)
{
cout << "(" << p.first->first << "," << p.first->second << ")inserted" << endl;
}
else
{//输出此信息
cout << "insertion failed" << endl;
}
mp["Harry"] = 78;//插入一元素,其first为“Harry”,然后将其second改为78
MP::iterator q = mp.find("Harry");
cout << "(" << q->first << "," << q->second << ")" << endl;
return 0;
}
map单词词频统计
#include <iostream>
#include <map>
#include <set>
#include <cstring>
using namespace std;
struct Word
{
int times;
string wd;
};
struct Rule
{
bool operator()(const Word& w1, const Word& w2)
{
if (w1.times != w2.times)
{
return w1.times > w2.times;
}
else
{
return w1.wd < w2.wd;
}
}
};
int main()
{
string s;
set<Word, Rule>st;
map<string, int>mp;
while (cin >> s)
{
++mp[s];
}
for (map<string, int>::iterator i = mp.begin();
i != mp.end(); ++i)
{
Word tmp;
tmp.wd = i->first;
tmp.times = i->second;
st.insert(tmp);
}
for (set<Word, Rule>::iterator i = st.begin();
i != st.end(); ++i)
{
cout << i->wd << " " << i->times << endl;
}
return 0;
}