ACM选修(栈与队列)

数字符号串->整数

//数字符号串存于exp数组中
int factor=0;
do
{//合并出运算对象的值
 factor=factor*10+exp[i]-48;
 i=i+1;
}while(isdigit(exp[i]));

括号匹配的检验

假设表达式中充许括号嵌套,则检验括号是否匹配的方法可用“期待的急迫程度”这个概念来描述。例:{ ( [ ……]…)…{ (……)……} }  

括号配对检查程序
执行过程中栈的变化:  #{ ( [ ……]…)…{ (……)……} }# 

 
[            
(
{
#
输入格式:一行一个括号序列,可以输入若干行
输出格式:一行一个输出结果,配对为YES,不配对为NO
样例:
输入样例:
{ ( [  ] ) ( ) [ ] }
[ ( ) ] ( ) { ( ) }
{()}[]])
输出样例
YES
YES
NO

/*括号配对*/

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

int fun(char *);

int main()
{
	char str[100];
	cin>>str;

	if(fun(str)==0)
		cout<<"NO"<<endl;
	else 
		cout<<"YES"<<endl;

	return 0;
}

int fun(char *str)
{
	unsigned int len;
	int i=0;
	stack<char>ch;
	len=strlen(str);

	for(i=0;i<len;i++)
	   switch(str[i])
	   {
		case '(':
		case '[':
		case '{':ch.push (str[i]);
			     break;
		case ')':if(ch.size ()==0)
					 return 0;
				 else
					 if(ch.top ()=='(') 
						 ch.pop();
					 else
						 return 0;
				 break;
		case ']':if(ch.size ()==0)
					 return 0;
				 else
					 if(ch.top ()=='[') 
						 ch.pop();
					 else
						 return 0;
				 break;
		case '}':if(ch.size ()==0)
					 return 0;
				 else
					 if(ch.top ()=='{') 
						 ch.pop();
					 else
						 return 0;
				 break;
		default:return 0;
	    }

	if(ch.size ()==0&&i==len)
		return 1;
	else
		return 0;
}



数制转换
十进制N和其它进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法基于原理: N=(n / d)*d+n % d

输入格式
若干行,每行两个数据,分别表示要转换的十进制数以及所要转换成的进制(2~9)。
输出格式
每行一个输出结果,即转换出来的结果
输入输出格式样例:
输入
10 2
10 8
10 5
输出
1010
12
20
例如(1348)10=(2504)8,其运算过程如下:  

nn/8n%8
13481684
168210
2125
202

#include<stack> 
#include<iostream> 
using namespace std; 
void main() 
{ int n; 
  stack<int> st; 
  cin>>n; 
  while(n!=0) {st.push(n%8);n=n/8;} 
  while( !st.empty( ) ) {cout<<st.top();st.pop();} 
  return;
}  

表达式的计算

1.后缀表达式的计算:

输入格式:一行一个后缀表达式,可以输入若干行
输出格式:一行一个输出结果
样例:
输入样例:
2 3 + 4*
6 2 / 3 *
输出样例
2 3 + 4*=20
6 2 / 4 *=12 

/*后缀表达式的计算*/

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

int main()
{
	int n=0;
	int temp=0;
	unsigned int i;
	char str[500];
	stack<int>num;
	gets(str);

	for(i=0;i<strlen(str);)
	   switch(str[i])
	   {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':temp=temp*10+str[i]-'0';
			     i++;
				 break;
		case ' ':if(str[i-1]<='9'&&str[i-1]>='0')
				 {
					 num.push (temp);
			         temp=0;
				 }
				 i++;
				 break;
		case '+':n=num.top ();
			     num.pop ();
			     n=num.top ()+n;
			     num.pop ();
			     num.push (n);
			     i++;
				 break;
		 case '*':n=num.top ();
			     num.pop ();
			     n=num.top ()*n;
			     num.pop ();
			     num.push (n);
			     i++;
				 break;
		 case '-':n=num.top ();
			     num.pop ();
			     n=num.top ()-n;
			     num.pop ();
			     num.push (n);
			     i++;
				 break;
		 case '/':n=num.top ();
			     num.pop ();
			     n=num.top ()/n;
			     num.pop ();
			     num.push (n);
			     i++;
				 break;
	    }

	cout<<n<<endl;

	return 0;
}

2.中缀表达式转换为后缀表达式:

输入格式:一行一个中缀表达式,可以输入若干行
输出格式:一行一个,输出相应的后缀表达式
样例:
输入样例:
2+(3 + 4)*5
16+ 2 * 30 /4
输出样例
2  3  4 + 5 * +
16  2  30 * 4 /  +

/*中缀转换为后缀*/

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

int main()
{
	stack<char>ch;
	queue<char>num;
	unsigned int i;
	char str[100];

	cout<<"请输入中缀表达式:";
	cin>>str;

	for(i=0;i<strlen(str);i++)
	   switch(str[i])
	   { 
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':num.push (str[i]);break;
		case '*':
		case '/':num.push(' ');
			     ch.push (str[i]);break;
		case '(':ch.push (str[i]);break;
		case '+':
		case '-':num.push (' ');
			    if(ch.size ()!=0)
			        while(ch.top ()=='*'||ch.top ()=='/')
				    {
					    num.push(ch.top());
					    ch.pop();
					    num.push (' ');
						if(ch.size ()==0) break;
				    }
			    ch.push (str[i]);
			    break;
		case ')':num.push(' ');
			    while(ch.top ()!='(')
				{
					num.push (ch.top ());
					ch.pop ();
					if(ch.top ()!='(')
						num.push (' ');
				}
				ch.pop ();
				break;
	    }

	cout<<"后缀表达式为:";

	while(ch.size ())
	{
		num.push(' ');
		num.push(ch.top());
		ch.pop();
	}

	while(num.size ())
	{
		cout<<num.front ();
		num.pop ();
	}

	cout<<endl;
	return 0;
}

3.中缀表达式的计算:

输入格式:一行一个中缀表达式,可以输入若干行
输出格式:一行一个输出结果
样例:
输入样例:
2*(3 + 4)
6+ 2 * 3 /4
输出样例
2*(3 + 4)
6+ 2 * 3 /4

/*中缀表达式的计算*/

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

int fun(char *,int );

int main()
{
	stack<char>ch,result;
	queue<char>num;
	unsigned int i;
	int n=0,temp=0;
	char str[100],res[200];

	cout<<"请输入中缀表达式:";
	cin>>str;

	for(i=0;i<strlen(str);i++)
	   switch(str[i])
	{ 
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':num.push (str[i]);break;
		case '*':
		case '/':num.push(' ');
			     ch.push (str[i]);break;
		case '(':ch.push (str[i]);break;
		case '+':
		case '-':num.push (' ');
			    if(ch.size ()!=0)
			        while(ch.top ()=='*'||ch.top ()=='/')
				    {
					    num.push(ch.top());
					    ch.pop();
					    num.push (' ');

						if(ch.size ()==0)
							break;
				    }
			    ch.push (str[i]);
			    break;
		case ')':num.push(' ');
			    while(ch.top ()!='(')
				{
					num.push (ch.top ());
					ch.pop ();

					if(ch.top ()!='(')
						num.push (' ');
				}
				ch.pop ();
				break;
	}

	while(ch.size ())
	{
		num.push(' ');
		num.push(ch.top());
		ch.pop();
	}

	for(i=0;num.size ()!=0;i++)
	{
		res[i]=num.front ();
		num.pop ();
	}

	cout<<fun(res,i-1)<<endl;
	return 0;
}

int fun(char *string,int len)
{
	int n=0,temp=0;
	unsigned int i;
	stack<int>result;

	for(i=0;i<=len;)
	   switch(string[i])
	   {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':temp=temp*10+string[i]-'0';
			     i++;break;
		case ' ':if(string[i-1]<='9'&&string[i-1]>='0')
				 {
					 result.push (temp);
			         temp=0;
				 }
				 i++;break;
		case '+':n=result.top ();
			     result.pop ();
			     n=result.top ()+n;
			     result.pop ();
			     result.push (n);
			     i++;break;
		 case '*':n=result.top ();
			     result.pop ();
			     n=result.top ()*n;
			     result.pop ();
			     result.push (n);
			     i++;break;
		 case '-':n=result.top ();
			     result.pop ();
			     n=result.top ()-n;
			     result.pop ();
			     result.push (n);
			     i++;break;
		 case '/':n=result.top ();
			     result.pop ();
			     n=result.top ()/n;
			     result.pop ();
			     result.push (n);
			     i++;break;
	}

	return n;
}



设有一个表L=(a1,a2,a3,…an),其中L为表名,a1,a2,…an为表中元素,当ai为数值时,表示一个元素值;当ai为大写字母时,表示另一个表,但不能循环定义。例如,
L=(3,4,8,S,9,0,8,T)
S=(10,3,4,U,9,6)
T=(4,5,6)
U=(7,9,8,6)
当给出全部表后,求出所有元素的最大元素。

输入格式
3,4,8,S,9,0,8,T
10,3,4,U,9,6
4,5,6
7,9,8,6
输出格式
10

void main()
{
   queue<char> qu;
   char str[255];
   int i,s, max=-32767;
   qu.push('A');
   while(!qu.empty())
   {
      qu.pop();
      cin.getline(str,255);
	  i=0;
      while(str[i]!='\0')
       {
         if (isdigit(str[i]))
		  {
		     s=0;
			 do{s=s*10+str[i]-48;i++;}while (isdigit(str[i]));
		    if (s>max) max=s;
		   }
		 else if ( isalpha(str[i])) {qu.push(str[i]);i++;}
         else i++;
		}
    }
  cout<<max;
}

家族关系
有一个大家族,目前存在着如下的关系,其中A是最年长的族长,如果给出双亲与孩子之间的关系,请计算出该家族是属于几代同堂的。
A有孩子B、C和D
B有孩子E、F和G
C有孩子H和I……

输入格式
3  1 2 3
3  4 5 6
2  7 8
4  9 10 11 12
0
0
0
0
2  13 14
0
0
输出:
4

#include<iostream>
#include<queue>
using namespace std;
struct queuenode
{
	int child;
	int level;
};
int generate(int root)
{
	 queue<queuenode> qu;   
	 queuenode temp,newtemp;
	 int child_num,child,i,maxlevel=0;

	 temp.child=root;
	 temp.level=1;
     
     qu.push(temp);  

	 while(!qu.empty())
	 {
		 temp=qu.front(); 	 qu.pop();
         if (temp.level>maxlevel) maxlevel=temp.level;
         cin>>child_num;
         for(i=0;i<child_num;i++) 
		 {
		 cin>>child;
		 newtemp.child=child;        
         newtemp.level=temp.level+1;
		 qu.push(newtemp);
		 }
	 }
     return maxlevel;
}


问题:机器调度
考察一个机械厂,其中有m台一模一样的机器。现有n个作业需要处理,设作业i的处理时间为ti,这个时间为从将作业放入机器直到从机器上取下作业的时间。所谓调度(schedule)是指按作业在机器上的运行时间对作业进行分配,使得:
一台机器在同一时间内只能处理一个作业。
一个作业不能同时在两台机器上处理。
作业i一旦运行,则需要ti个时间单位。

例如,在一个C/C++程序中有如下嵌套调用的主函数main( )和三个函数f1( ),f2( ),f3( ):七个作业在三台机器上进行调度的情形,七个作业所需时间分别为(2, 14,4, 16, 6, 5, 3)。三台机器分别被编号为M1、M2和M3。
Task: 确定如何进行调度才能使在m台机器上执行给定的n个作业时所需要的处理时间最短
Solution:采用一个称为最长处理时间优先(Longest Processing Time first, LPT)的简单调度策略,在LPT算法中,
(1)作业按它们所需处理时间的递减顺序排列,即生成最大优先队列。
(2)由于在分配一个作业时,总要将其分配给最先变为空闲的机器,因此机器也按空闲的到来时刻生成一个最小优先队列,看谁快进入空闲状态。


问题
在一个序列中依次找出最小的两个值,并将它们的和值放入序列中,而将它们去掉,反复执行如此操作,直到剩下一个元素位置,最后输出该元素值以及整个选择过程。
输入输出样例:
输入:
6 6 2 3 3 4 9
输出
2 3  5
3 4  7
5 6 11
7 9 16
11 16 27

#include <queue>
#include <iostream>
using namespace std;

struct node 
{	  int data;
        node(int i) { data=i; }
};

bool operator<(const node &a,const node &b)
{	if(a.data>b.data ) return true;  else   return false;	}

int main()  {
	node x(0);
	priority_queue<node> p;
	p.push(node(3));	p.push(node(9));	p.push(node(5));
	while( !p.empty( ) ) {   x=p.top();    p.pop();  cout<<x.data<<" ";	}
      return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值