天天看点

9.28 算法入门STL初步 vector set

今天正式开始了算法学习,明显感到脑力不支,还是基础问题。

1、函数模板和类模板:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。

2、排序与检索:使用algorithm头文件中的sort和lower_bound分别完成排序和在已排数组中检索(例:Where is the Mables?)

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10000;
int main()
{
	int n,q,x,a[maxn],kase = 0;
	while(scanf("%d%d",&n,&q) == 2 && n) {
		printf("CASE# %d:\n",++kase);
		for(int i=0;i<n;i++) scanf("%d",&a[i]);
		sort(a,a+n);//排序
		while(q--)
		{
			scanf("%d",&x);
			int p = lower_bound(a,a+n,x)-a;//在已排序数组a中寻找x
			if(a[p] == x)  printf("%d dound at %d\n",x,p+1);
			else printf("%d not found\n",x);
		}
	}
	return 0;
}
           

3、STL中的vector、set、map容器 

(1)不定长数组vector:(例:The Block Problem)

A.定义:是一个模板类。一些常用操作封装在vector类型内部。如,a.size()读取大小;a.resize()改变大小;a.push_back()向尾部添加元素;a.pop_back()删除最后一个元素;clear()清空;empty()测试是否为空。像是“一等公民”,vector之间可以直接赋值或者作为函数的返回值。vector<int> a或vector<double> b

B.像一个二维数组,第一维的大小固定,但不超过maxn,第二维大小不固定,可以认为是pile[p].size() 。

#include<cstdio>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn];//每一个pile[i]是一个vector
//找木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a,int & p,int & h)
{
	for(p = 0;p < n;p++)
		for(h = 0;h < pile[p].size();h++)
			if(pile[p][h] == a) return;//pile其实是一个二维数组
}

//把第P堆高度为h的木块上方的所有木块移回原位
void clear_above(int p,int h)
{
	for(int i = h+1;i < pile[p].size();i++)
	{
		int b = pile[p][i];
		pile[b].push_back(b);//把木块b放回原位 push_back()向尾部添加元素
	}
	pile[p].resize(h+1);
}//pile只应保留下0~h元素

//把第p堆高度为h及其上方的木块整体移动到p2堆的顶部
void pile_onto(int p,int h,int p2)
{
	for(int i = h;i < pile[p].size();i++)
		pile[p2].push_back(pile[p][i]);//1放在2的顶部即2放在1的底部
	pile[p].resize(h);
}
void print()
{
	for(int i = 0;i < n;i++)
	{
		printf("%d:",i);
		for(int j = 0;j < pile[i].size();j++) printf("%d",pile[i][j]);
		printf("\n");
	}
}
int main()
{
	int a,b;
	cin>>n;
	string s1,s2;
	for(int i = 0;i < n;i++) pile[i].push_back(i);
	while(cin>>s1>>a>>s2>>b)
	{
		int pa,pb,ha,hb;
		find_block(a,pa,ha);
		find_block(b,pb,hb);
		if(pa == pb) continue;
		if(s2 == "onto") clear_above(pb,hb);
		if(s1 == "move") clear_above(pa,ha);
		pile_onto(pa,ha,pb);
	}
	print();
	return 0;
}
           

(2)集合set:(例:Anday's First Dictionary)

set<int> a

#include<iostream>
#include<string>
#include<set>
#include<sstream>
using namespace std;
set<string> dict;//string 集合
int main()
{
<span style="white-space:pre">	</span>string s, buf;
<span style="white-space:pre">	</span>while (cin >> s) {
<span style="white-space:pre">		</span>for (int i = 0; i < s.length(); i++)
<span style="white-space:pre">		</span>if (isalpha(s[i])) s[i] = tolower(s[i]); else s[i] = " ";
<span style="white-space:pre">		</span>stringstream ss(s);
<span style="white-space:pre">		</span>while (ss >> buf) dict.insert(buf);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>for (set<string>::iterator it = dict.begin(); it != dict.end(); ++it)
<span style="white-space:pre">		</span>cout << *it << "\n";
<span style="white-space:pre">	</span>return 0;
}
           

a. stringstream  字符串流,绑定流与string对象字符串。

b.  isalpha() 判断是否为英文字符,是,返回1;不是,返回0;

c.     tolower() 转换为小写字母;

d. ss>>buf()把ss中的内容复制到buf(缓冲区)中;

e.  dict.insert(buf)insert是某部分函数的自带功能;

f. iterator 迭代器,类似于指针,vector类似于数组,用法类似。