数字符号串->整数
//数字符号串存于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,其运算过程如下:
n | n/8 | n%8 |
1348 | 168 | 4 |
168 | 21 | 0 |
21 | 2 | 5 |
2 | 0 | 2 |
#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;
}