數據結構基礎 | 棧和隊列練習

數據結構和算法這基礎鴨,在上研究生之前還是要好好鞏固好的。那麼!從今天開始就堅持每日一小節趴!害,我這無處安放的勤奮學習的心啊~~ 剛把得!


例題6-2 鐵軌

某城市有一個火車站,有n截車廂從A方向駛入,按進站順序編號1-n。判斷能否按照特定的順序進入B方向的鐵軌駛出車站

解法:棧的簡單運用
代碼:

//判斷出棧順序是否可能
#include<cstdio>
#include<stack>
using namespace std;
const int MAXN=1000+10;
int n, target[MAXN];
int main(){
	while(scanf("%d",&n)==1){
		stack<int> s;
		int A=1,B=1;
		for(int i=1;i<=n;i++)
			scanf("%d",&target[i]);
		int ok=1;
		while(B<=n)
		{
			if(A==target[B]){A++;B++;}
			else if(!s.empty() && s.top()==target[B]){s.pop();B++;}
			else if(A<=n)s.push(A++);
			else {ok=0; break;}
		}
		printf("%s\n",ok?"yes":"no");
	}
	return 0;
}


例題6-3 矩陣鏈乘

輸入n個矩陣的維度和一些矩陣鏈乘表達式,輸出乘法的次數。如果無法相乘輸出error。假定A是mxn矩陣,B是nxp矩陣,乘法次數位mxnxp。
例如,A是50x10的,B是1020的,C是205的,則(A(BC))的乘法次數爲10x20x5(BC的乘法次數)+50x10x5(A(BC))的乘法次數)=3500

解法: 分析表達式,用棧解決,碰到字母時進展,碰到右括號出棧計算,將結果存棧。

代碼:

#include <cstdio>
#include <stack>
#include<iostream>
#include <string>
using namespace std;

struct Matrix{
	int a, b;
	Matrix(int a=0,int b=0):a(a),b(b){}
}m[26];

stack<Matrix> s;
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		string name;
		cin>>name;
		int k=name[0]-'A';
		cin>>m[k].a>>m[k].b;
	}
	string expr;
	while(cin>>expr){
		int len=expr.length();
		bool error=false;
		int ans=0;
		for(int i=0;i<len;i++)
		{
			if(isalpha(expr[i])) s.push(m[expr[i]-'A']);
			else if(expr[i]==')'){
				Matrix m2=s.top();s.pop();
				Matrix m1=s.top();s.pop();
				if(m1.b !=m2.a){ error=true;break;}
				ans+=m1.a*m1.b*m2.b;
				s.push(Matrix(m1.a,m2.b));
			}
		}
		if(error) printf("error\n");
		else printf("%d\n",ans);
	}
	return 0;
}

描述

實現一個棧,完成以下功能:入棧、出棧、詢問棧中位置Y是誰

一開始棧爲空。棧中的位置從1開始(即棧底位置爲1)。

輸入

第一行一個整數n,表示操作個數。
接下來n行,每行第一個數字表示操作(見描述):
若爲數字1,則接下來有一串字符串X,表示將X壓入棧中。
若爲數字2,表示彈出棧頂(保證棧非空),並輸出出棧的這個人。
若爲數字3,則接下來有一個整數Y,表示詢問棧中位置Y是誰(保證位置Y合法),並輸出名字

輸出

將所有操作2和操作3輸出,一行一個。

代碼:

#include <iostream>
using namespace std;
const int N=100005;
	//Stack:棧
	//top:棧頂位置
	string Stack[N];
	int n,top=1;

	//壓入棧頂
	//name:被壓入的人的姓名
	void push(string name)
	{
		Stack[top]=name;top++;
	}

	//彈出棧頂
	//返回值:被彈出來的人的name
	string pop(){
	return Stack[(top--)-1];//--top 和top--的區別
	}
	//詢問棧中某個位置上的人的姓名(棧底位置爲1,向棧頂方向的位置依次遞增)
	//pos:詢問位置
	//返回值:pos上的name
	string query(int pos){
		return Stack[pos];
	}
int main()
{
	cin>>n;
	char name[20];
	for( ;n--;)
	{
		int m; cin>>m;
		switch(m)
		{
			case 1:
				cin>>name;push(name);break;
			case 2:
				cout<<pop().c_str()<<endl;//c_str是Borland封裝的String類中的一個函數,它返回當前字符串的首字符地址。
				break;
			case 3:
				int pos;cin>>pos;
				cout<<query(pos).c_str()<<endl;
				break;
		}
	}
	return 0;
}

題目與上面相同 改成隊列形式

#include <iostream>
using namespace std;
const int N=100005;
	//Queue:隊列
	//first:隊頂位置
	string Queue[N];
	int n,first=1,rear=1;

	//壓入隊列
	//name:被壓入的人的姓名
	void inqueue(string name)
	{
		Queue[rear]=name;rear++;
	}

	//輸出隊列
	//返回值:被彈出來的人的name
	string dequeue(){
	return Queue[first++]; 
	}
	//詢問隊列中某個位置上的人的姓名
	//pos:詢問位置
	//返回值:pos上的name
	string query(int pos){
		return Queue[pos+first-1];//ahhhhhhh 我真是個天才,,,雖然底子差 但是自己想出來的感覺真爽!
	}
int main()
{
	cin>>n;
	char name[20];
	for( ;n--;)
	{
		int m;
		cin>>m;
		switch(m)
		{
		case 1:
			cin>>name;inqueue(name);
			break;
		case 2:
			cout<<dequeue().c_str()<<endl;//c_str是Borland封裝的String類中的一個函數,它返回當前字符串的首字符地址。
			break;
		case 3:
			int pos;
			cin>>pos;
			cout<<query(pos).c_str()<<endl;
			break;
		}
	}
	return 0;
}

參考博客:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章