复习

1
2
3
4
5
6
strcpy(str1, str2);  // 字符串拷贝函数
strcat(str1, str2);  // 字符串拼接函数,将str2的内容拼接到str1后边
strcmp(str1, str2);  // 字符串比较函数, str1>str2时输出的是正整数,str1<str2时输出负整数,当str1和str2一样的时候输出0
strlen(str); 	// 输出字符串的长度,不包括'\0'
puts(str); 		// 输出字符串 类似于printf("%s", str);
gets(str); 		// 输入字符串, 可以输入空格

STL入门

vector

vector:可变长数组

创建vector的四种方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 第一种创建vector的方法 
vector<double> values;

// 第二种创建vector的方法
vector<double> values1(20);

// 第三种创建vector的方法 
vector<double> numbers(20, 2.3); 
//不仅开辟了20个元素的空间,并且给每个元素赋初值为2.3 

// 第四种创建vector的方法
double d[6] = {1,2,3,4,5,6};
vector<double> words(d+1, d+5); 
// 给定一个区间,将区间内的数据拷贝到vector中作为初值。

修改vector的数据

1
2
3
4
//修改vector内部的数据
cout<<endl;
words[2] = 1;
vec_tra(words);  //遍历

删除vector中的数据

1
2
3
4
5
6
7
8
9
// 从vecotr中删除元素
cout<<"before del size : "<<words.size()<<endl;
vec_tra(words);
words.pop_back();
cout<<"after del size : "<<words.size()<<endl;
vec_tra(words);
	
words.clear();
cout<<"after clear size : "<<words.size()<<endl;

迭代器

1
2
3
4
5
6
7
8
9
// 迭代器的应用
vector<double>::iterator it=words.begin(); //让it指向words的第一个元素
while(it!=words.end()){ // 如果it不指向words的最后一个元素,就执行循环体 
		cout<<*it<<endl; // * 表示取内容, *it表示把 
		it++; // it向后挪动一个元素的位置,指向下一个元素 
} 
	
for(vector<double>::iterator it=words.begin(); it!=words.end(); it++)
	cout<<*it<<endl; 

stack

“先进后出”数据结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <stack>

using namespace std;

int main()
{
	stack<char> st; // 创建一个栈容器
	
	char str[] = "abcdefgj";
	
	for(int i=0; str[i]!='\0'; i++)
		st.push(str[i]);  // 将元素入栈 
	
	// 出栈
	while(!st.empty()) {
		cout<<st.top()<<endl;  // 获取栈顶元素 
		st.pop(); // 将栈顶元素出栈 
	} 
}

stack三种操作:创建、入栈、出栈

queue

“先进先出"数据结构

 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 <iostream>
#include <queue>

using namespace std;

int main()
{
	queue<char> q; 
	char str[]="abckegf";
	
	// 入队 
	for (int i=0; str[i]!='\0'; i++)
	{
		cout<<str[i]<<"入队"<<endl;
		q.push(str[i]);
	}
	cout<<"入队完成, 队列中元素个数"<<q.size()<<endl;
	
	// 出队
	while(!q.empty()) {
		cout<<"队头元素:"<<q.front()<<endl;
		q.pop();
		cout<<"出队一个元素后队列中剩余元素个数"<<q.size()<<endl; 
	} 
	return 0;
} 

queue三种操作:创建、入队、出队

set

 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
44
45
#include <iostream>
#include <set> //引入头文件 

using namespace std;

int main()
{
	set<int> st1; // 创建一个set容器 
	set<int>::iterator it; // 创建一个set容器的迭代器 
	
	if (st1.empty()) 
		cout<<"空set"<<endl; 
	
	cout<<"插入四个元素"<<endl; 
	st1.insert(10);
	st1.insert(20);
	st1.insert(50);
	st1.insert(30);
	cout<<"现在set中元素个数:"<<st1.size()<<endl;
	
	cout<<"遍历set"<<endl;
	for (it=st1.begin(); it!=st1.end(); it++) 
		cout<<*it<<endl;
		
	cout<<"查找30 : ";
	if(st1.find(30) != st1.end()) 
		cout<<"yes"<<endl;
	else 
		cout<<"no"<<endl;
		
	cout<<"查找40 : ";
	if(st1.find(40) != st1.end()) 
		cout<<"yes"<<endl;
	else 
		cout<<"no"<<endl;
		
	cout<<"删除30"<<endl;
	st1.erase(30);
	cout<<"删除后set中元素个数:"<<st1.size()<<endl;
	cout<<"清空set"<<endl;
	st1.clear(); 
	cout<<"set中元素个数:"<<st1.size()<<endl; 
	
	return 0;
}

创建、插入元素、删除元素、查找元素

map

 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
44
#include <map>
#include <string>
#include <iostream>

using namespace std;

int main()
{
	map<int, string> id_name;
	map<int, string>::iterator it; 
	
	cout<<"插入四个元素"<<endl; 
	id_name[12] = "xiaoming";
	id_name[1] = "xiaohong";
	id_name[27] = "zhangsan";
	id_name[5] = "lisi";
	cout<<"现有元素个数:"<<id_name.size()<<endl;
	
	//遍历
	cout<<"遍历"<<endl; 
 	for(it=id_name.begin(); it!=id_name.end(); it++)
 		cout<<(*it).first<<" "<<(*it).second<<endl;
 		
 	// 查询
	if (id_name.count(12) != 0) 
		cout<<"id_name[12] = "<<id_name[12]<<endl;
	else 
		cout<<"id_name中没有key为12的元素"<<endl; 
	
	if (id_name.find(17) != id_name.end())
		cout<<"id_name[17] = "<<id_name[17]<<endl;
	else
		cout<<"id_name中没有key为17的元素"<<endl;
		
	// 删除
	cout<<"删除key为12的元素"<<endl;
	id_name.erase(12);
	cout<<"删除后map中还有元素个数"<<id_name.size()<<endl;
	cout<<"删除后map中的元素为"<<endl;
 	for(it=id_name.begin(); it!=id_name.end(); it++)
 		cout<<(*it).first<<" "<<(*it).second<<endl; 
 	// 清空
	id_name.clear(); 		
} 

创建、插入元素、查找元素、删除元素

掌握下边统计字符出现次数的程序

 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 <iostream>
#include <map>
#include <cstring>

using namespace std;

int main()
{
	map<char, int> wordt;
	char  a[100000];
	cin>>a;
	int len = strlen(a);
	for (int i=0; i<len; i++) 
		wordt[a[i]]++;  // a[i]即字符串中的字符,是key, value是a[i]出现的次数
		// wordt[a[i]] 是 以a[i]为key对应的value的值,即a[i]出现的次数,
		// 后边的++是将次数加一的意思  
		
	map<char, int>::iterator it;
	for (it=wordt.begin(); it!=wordt.end(); it++)
	{
		//cout<<(*it).first<<"  "<<(*it).second<<endl;
		if((*it).second == 1) 
		{
			cout<<(*it).first;
			//return 0;
		}
	}
	return 0;		
}

string的常用操作

搜索操作

string类提供了6个不同的搜索函数,每个函数有4个重载版本。每个操作都返回一个string::size_type值。表示匹配发生位置的下标。如果搜索失败,则返回一个名为string::nposstatic成员。(const string::size_type npos=-1,是一个unsigned类型)

函数名解释
s.find(args)查找s中args第一次出现的位置
s.rfind(args)查找s中args最后一次出现的位置
s.find_first_of(args)在s中查找args中任何一个字符第一次出现的位置
s.find_last_of(args)在s中查找args中任何一个字符最后一次出现的位置
s.find_first_not_of(args)在s中查找第一个不在args中的字符
s.find_last_not_of(args)在s中查找最后一个不在args中的字符
args的4种重载
类别解释
c ,pos从s中位置pos开始查找字符c, pos默认为0
s2, pos从s中位置pos开始查找字符串s2, pos默认为0
cp, pos从s中位置pos开始查找指针cp指向的以空字符串结尾的c风格字符串, pos默认为0
cp, pos, n从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值

Eg1:

string name("AnnaBelle");
auto pos = name.find("Anna"); // pos = 0

auto pos = name.find("anna"); // pos = string::npos

string numbers("0123456789"), name("r2d2");
auto pos = name.find_first_of(numbers); // pos = 1

string dept("0375p3");
auto pos = dept.find_first_not_of(numbers); // pos = 4

Eg2:

1
2
3
4
5
6
string::size_type pos = 0;
// 每步循环查找name中下一个数字。
while ((pos = name.find_first_of(numbers, pos)) != string::npos) { 
  cout<<"found number at index : "<<pos<<" element is "<<name[pos]<<endl;
  ++pos; // 如果忽略递增pos,将成为一个死循环
}

构造操作

函数解释
string s(cp, n)s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符
string s(s2, pos2)s是string s2从下标pos2开始的字符的拷贝
string s(s2, pos2, len2)s是s2从下标pop2开始len2个字符的拷贝

这些构造函数接受一个string或者一个const char *参数,还接受指定拷贝多少个字符的参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const char *cp = "hello world!!"; // 以空字符结束的数组
char noNull[] = {'H','e'};	// 不是以空字符结束
string s1(cp);					// 拷贝cp中的字符直到遇到空字符, s1 = "hello world!!"
string s2(noNull, 2);		// 从noNull中拷贝两个字符
string s3(noNull);			// 未定义,noNull不是以空字符结束的
string s4(cp+6, 5);			// 从cp[6]开始拷贝5个字符 s4 = "world"
string s5(s1, 6, 5);		// 从cp[6]开始拷贝5个字符 s5 = "world"
string s6(s1, 6);				// 从cp[6]开始拷贝直到结尾 s6 = "world!!"
string s7(s1, 6, 20);		// 从cp[6]开始拷贝直到结尾 s7 = "world!!"
string s8(s1, 16);			// 抛出一个out_of_range异常

通常从const char *创建string时,只恨指向的数组必须以空字符结尾,拷贝操作遇到空字符时停止。如果未传递计数值且数组也未以空字符结尾,或者给定的计数值大于数组大小,则构造函数的行为是未定义的。

当从string拷贝字符串时,我们可以提供一个可选的开始位置和一个计数值。开始位置必须小于或者等于个定的string的大小。如果位置大于size,则构造函数抛出一个out_of_range异常。如果我们传递一个计数值,则从给定位置开始拷贝这么多个字符。不管要求拷贝多少个字符,最多拷贝到string的结尾。

substr

substr操作返回一个string

1
2
3
4
5
string s("hello world");
string s2 = s.substr(0, 5); // s2 = hello
string s3 = s.substr(6);		// s3 = world
string s4 = s.substr(6, 11);// s4 = world	
string s5 = s.substr(12);		// 抛出一个out_of_range的异常