天天看點

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類似于數組,用法類似。