程序设计与算法郭炜老师的课堂笔记1

  • 基础
  • 与或非
  • 位运算
  • 字符串操作库函数
    • strtok尝试
    • 字符串0新认识
  • void 指针无定义
  • 快排
  • 变量
  • 排序
  • Vector
    • vector示例
    • 用**vector**实现二维数组
    • 大整数类
  • Deque
  • List
  • Queue
  • STL算法
    • 用sort进行排序
    • 自定义排序规则
    • 用sort进行排序二
    • 用sort进行排序三:对结构进行排序
    • STL查找是在排好序的数组上进行二分查找
      • binary_search进行二分查找
      • lower_bound 二分查找下界
      • upper_bound 二分查找下界
    • STL中的平衡二叉树数据结构
    • multiset
      • 自定义规则的multiset
      • 自定义结构的规则的multiset
    • set
    • multimap
    • map
      • map单词词频统计

基础

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) 操作次数和问题无关
    • 对数复杂度
    • 线性复杂度
    • 多项式复杂度
    • 指数复杂度
    • 阶乘复杂度
  1. 无序数列中查找一个数:0(n)
  2. 平面上有n个点,找出任意两点间距离 0(n^2)
  3. 插入排序、选择排序、冒泡排序 0(n^2)
  4. 快速排序 0(n*log(n)) 快排的最坏复杂度就是0(n^2)是已经排好序的
  5. 二分查找 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(n
log(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的内容放入vcout << "1) " << v.end() - v.begin() << endl;
//两个随机迭代器可以相减,输出 1) 5cout << "2) ";PrintVector(v.begin(), v.end());
//2)    1 2 3 4 5v.insert(v.begin() + 2, 13); //在begin()+2位置插入    13cout << "3) ";PrintVector(v.begin(), v.end());
//3)    1 2 13 3    4   5v.erase(v.begin() + 2); //删除位于    begin() +  2的元素cout << "4) ";PrintVector(v.begin(), v.end());
//4)    1 2 3 4 5vector<int> v2(4, 100);    //v2 有4个元素,都是100v2.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 100v.erase(v.begin() + 1, v.begin() + 3);
//删除    v 上的一个区间,即  2,3cout << "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并清空lst2cout << "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 7int 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中的平衡二叉树数据结构

  1. 需要在大量增加,删除数据的同时,还要进行大量数据的查找

  2. 希望增加数据,删除数据,产找数据都能在log(n)复杂度完成

  3. 排序+二分查找显然不可以,因加入新数据就要重新排序

    就可以使用“平衡二叉树”数据结构存放数据,体现在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);//插入22i = 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指向的元素,即12for (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.infoelse 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;//输出98mp["Jack"] = 60;//修改名为“Jack”的元素的secondfor (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改为78MP::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;
}

程序设计与算法郭炜老师的课堂笔记1相关推荐

  1. 程序设计与算法郭炜老师的课堂笔记2

    程序设计与算法郭炜老师的课堂笔记2 枚举 完美立方 生理周期 称硬币 熄灯问题 递归 求阶乘 汉诺塔 N皇后 逆波兰表达式 表达式求值 上台阶 放苹果 算24 二分算法 找一对数 分治 归并排序 快速 ...

  2. 程序设计与算法郭炜老师的课堂笔记3

    程序设计与算法郭炜老师的课堂笔记3 从C到C++ 引用 引用作为函数参数 引用作为函数返回值 常引用 const关键字 定义常量 定义常量指针 定义常引用 动态内存分配 用new开内存 用delete ...

  3. xmuoj《C++与Python语法入门练习(By郭炜老师)》python参考代码

    目录 前言 xmuoj对应链接 Pycharm安装 代码 001 输出第二个整数 002 字符菱形 003 打印ASCII码 004 打印字符 005 整型数据类型存储空间大小 006 浮点型数据类型 ...

  4. AI公开课:19.04.17杨松帆—好未来AI Lab负责人《为人工智能时代打造一个AI老师》课堂笔记以及个人感悟

    AI公开课:19.04.17杨松帆-好未来AI Lab负责人<为人工智能时代打造一个AI老师>课堂笔记以及个人感悟 导读 杨松帆,现为好未来教育集团人工智能实验室负责人.曾任FaceThi ...

  5. 郭炜老师 程序设计与算法(二) 枚举

    枚举:(一)完美立方 题目: 题解: 设计abcd四个属性的遍历范围和遍历顺序,使用for循环进行遍历 总结: 枚举需要注意枚举的范围,一般只需要给出一个大致范围,不需要十分精确的计算 枚举还需要注意 ...

  6. 例题代码|程序设计与算法(二) 算法基础 北大 郭炜 中国大学MOOC 笔记

    网站链接

  7. 郭炜老师魔兽三备战思路及代码

    这个题目,我花了差不多4天才全部做出来的,一开始也没很好的设计,就是看见有什么功能,就写一个函数的声明,然后写另一个类的时候,发现我要用到前面写的类的函数时,才去定义相应的函数,所以可能会很混乱.我写 ...

  8. 北大郭炜《程序设计与算法(三)》Mooc笔记:运算符重载和继承

    文章目录 运算符重载 运算符重载的基本概念 赋值运算符的重载 为什么引入赋值运算符重载? 浅拷贝和深拷贝 对operator=返回值的讨论 复制构造函数的相同困境 运算符重载为友元函数 实例:可变长数 ...

  9. Python1.语言基本要素上(郭炜老师python大学mooc)

    首先是 程序中的所有字符都必须是英文字符,不能是中文的全角字符, 除非输出中文,才会在"字符串"中使用中文 目录 一.注释 二.变量 三.赋值语句 四.字符串初步 五.字符串和数的 ...

最新文章

  1. Nmap Windows 版本时区显示乱码
  2. Apollo进阶课程㉑丨Apollo规划技术详解——Basic Motion Planning and Overview
  3. OpenVINO Inference Engine之LoadNetwork
  4. Elasticsearch】 es Match Query
  5. 编译安装imagick出错:make: *** [imagick_class.lo] Error 1
  6. 华为-----任正非
  7. shiro 认证和授权原理
  8. windows PAE扩展和AWE编程
  9. MFC加入mysql后编译成功,在自己电脑上成功运行,当打包发送到其他电脑上报错, 缺少libcrypto-1_1-x64.dll以及缺少libssl-1_1-x64.dll问题解决方案,完美亲测
  10. Linux自学之MPD
  11. erp5,一套基于python和gpl协议,功能和界面完全模仿sap r3的大型开源制造业erp系统
  12. 德卡t10社保卡类型_德卡T10社保卡读卡器非接触式ic卡医保卡二代证医院挂号卡...
  13. snkrs抽签协议获取
  14. 2908. Annoying painting tool
  15. 我如何构建Pomodoro Clock应用程序,以及在此过程中学到的课程
  16. vue axios常用写法
  17. 【Qcom Camera】微距eeprom调试
  18. 解决Python打包exe控制台无法粘贴问题
  19. “伪智能”厂商能有什么坏心思,无非是想骗钱罢了
  20. python 英语分词是什么意思_英语里面现在分词是什么意思

热门文章

  1. windows下架设SVN服务器并设置开机启动
  2. spring引入多个properties文件
  3. 小米杀不死的消息推送-- Android、java后端同时接入小米推送
  4. NEIL: Extracting Visual Knowledge from Web Data 论文笔记
  5. 英语中的九大状语从句
  6. 基于区块链技术的智慧供应链创新应用
  7. jQuery实现点击文本框弹出热门标签的提示示例
  8. 脚本引擎《游戏脚本的设计与开发》-序
  9. C++ 中的指针参数传递和引⽤参数传递
  10. filecoin lotus 图形化测试平台pond