數據結構和算法這基礎鴨,在上研究生之前還是要好好鞏固好的。那麼!從今天開始就堅持每日一小節趴!害,我這無處安放的勤奮學習的心啊~~ 剛把得!
例題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;
}
參考博客: