设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是:4 (2分)
- 1
- 3
- 5
- 1或者5
允许出栈和进栈交替进行
7-2 符号配对 (20 分)
请编写程序检查C语言源程序中下列符号是否配对:/*
与*/
、(
与)
、[
与]
、{
与}
。
输入格式:
输入为一个C语言源程序。当读到某一行中只有一个句点.
和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。
输出格式:
首先,如果所有符号配对正确,则在第一行中输出YES
,否则输出NO
。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号
;如果缺少右符号,则输出左符号-?
。
输入样例1:
void test()
{
int i, A[10];
for (i=0; i<10; i++) /*/
A[i] = i;
}
.
输出样例1:
NO
/*-?
输入样例2:
void test()
{
int i, A[10];
for (i=0; i<10; i++) /**/
A[i] = i;
}]
.
输出样例2:
NO
?-]
输入样例3:
void test()
{
int i
double A[10];
for (i=0; i<10; i++) /**/
A[i] = 0.1*i;
}
.
输出样例3:
YES
作者: DS课程组
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
#define debug(a,n) for(int i=0;i<n;++i)cout<<a[i]<<' ';cout<<endl;
#define FRER() freopen("i.txt","r",stdin)
//库函数头文件包含
#include<bits/stdc++.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
using namespace std;
typedef int Status;
typedef char SElemType; //假设线性表中的元素均为整型
typedef struct
{
SElemType *base;
SElemType *top;
} SqStack;
Status InitStack(SqStack &S)
{
int M=100;
S.base=(SElemType*)malloc(M*sizeof(SElemType));
if(S.base==NULL)
exit(ERROR);
S.top=S.base;
return OK;
}
Status Push(SqStack &S,SElemType e)
{
*(S.top)=e;
S.top++;
return OK;
}
Status Pop(SqStack &S)
{
S.top--;
}
SElemType Top(SqStack &S)
{
return *(S.top-1);
}
Status Empty(SqStack &S)
{
if(S.base==S.top)
return OK;
else
return ERROR;
}
char c;
bool Compair(SqStack &S)
{
char ch[200];
int flag=1;
while(cin.getline(ch,sizeof(ch)))//sizeof(ch)==200,gets在c++11中已不能使用
{
if(ch[0]=='.'&&ch[1]=='\0')
break;
for(int i=0; ch[i]!='\0'; i++)
{
if(ch[i]=='('||ch[i]=='{'||ch[i]=='[')
{
Push(S,ch[i]);
}
else if(ch[i]=='/'&&ch[i+1]=='*')
{
Push(S,ch[i]);
Push(S,ch[i+1]);
i++;
}
else if(ch[i]=='*'&&ch[i+1]=='/')
{
if(!Empty(S)&&Top(S)=='*')
{
Pop(S);
if(!Empty(S)&&Top(S)=='/')
{
Pop(S);
i++;
}
else
{
c=ch[i];
flag=0;
break;
}
}
else
{
c=ch[i];
flag=0;
break;
}
}
else if(ch[i]==')')
{
if(!Empty(S)&&Top(S)=='(')
{
Pop(S);
}
else
{
c=ch[i];
flag=0;
break;
}
}
else if(ch[i]=='}')
{
if(!Empty(S)&&Top(S)=='{')
{
Pop(S);
}
else
{
c=ch[i];
flag=0;
break;
}
}
else if(ch[i]==']')
{
if(!Empty(S)&&Top(S)=='[')
{
Pop(S);
}
else
{
c=ch[i];
flag=0;
break;
}
}
}
}
if(Empty(S)&&flag)
return true;
else
return false;
}
int main()
{
SqStack S;
InitStack(S);
if(Compair(S))
printf("YES\n");
else
{ printf("NO\n");
if(!Empty(S))
{
if(Top(S)=='*')
printf("/*-?");
else if(Top(S)=='{')
printf("{-?");
else if(Top(S)=='(')
printf("(-?");
else if(Top(S)=='[')
printf("[-?");
}
else
{ if(c=='*')
printf("?-*/");
else
printf("?-%c",c);
}
}
return 0;
}
///*/或*/是成对出现的,而且总会出现一对不行,其他的不可以
中缀式转后缀式规则
****遇到数字直接输出,遇到左括号直接放进栈中,遇到右括号将栈顶元素依次输出直到遇到左括号(左括号也删除,右括号不再放进去),其他操作符直接和栈顶元素比较,1,优先级比栈顶元素低,栈顶元素依次出栈直到出现比该操作符优先级更小的(相同操作符也输出),该操作符最后还要放入栈中。2否则直接将该操作符放入栈中。最后将栈清空(乘除优先加减)
****
7-1 表达式转换 (25 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、\
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
#define debug(a,n) for(int i=0;i<n;++i)cout<<a[i]<<' ';cout<<endl;
#define FRER() freopen("i.txt","r",stdin)
//库函数头文件包含
#include <stdio.h>
#include <stdlib.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
using namespace std;
typedef int Status;
typedef char SElemType; //假设线性表中的元素均为整型
typedef struct
{
SElemType *base;
SElemType *top;
} SqStack;
Status InitStack(SqStack &S)
{
int M=60;
S.base=(SElemType*)malloc(M*sizeof(SElemType));
if(S.base==NULL)
exit(ERROR);
S.top=S.base;
return OK;
}
Status Push(SqStack &S,SElemType e)
{
*(S.top)=e;
S.top++;
return OK;
}
Status Pop(SqStack &S)
{
S.top--;
}
SElemType Top(SqStack &S)
{
return *(S.top-1);
}
char c='&';//用这种符号来分割后缀式的所有元素,好输出
Status Empty(SqStack &S)
{
if(S.base==S.top)
return OK;
else
return ERROR;
}
bool Number(SElemType e)
{
if(e>='0'&&e<='9')
return OK;
else
return ERROR;
}
bool Bigger(SElemType e,SElemType f)
{
//比较栈顶元素和其他的元素的大小的大小
if(e==f)
return OK;
if(e=='(')
return ERROR;
//按在字符串中的顺序看符号优先级
char ch[4]= {'+','-','*','/'};
int i,j;
for(i=0; i<=4; i++)
if(ch[i]==e)
break;
for(j=0; j<=4; j++)
if(ch[j]==f)
break;
if(i<j)
return ERROR;
return OK;
}
int main()
{
SqStack S;
InitStack(S);
SElemType ch[50];
SElemType che[100];
int flag=0;
int first=0;
scanf("%s",ch);
for(int i=0; ch[i]!='\0'; i++)
{//考虑(负数/正数)的情况
if(ch[i]=='-'||ch[i]=='+')
{
if(i>0)
{
if(ch[i-1]=='(')
{
if(ch[i]=='+')
continue;
else
{
che[flag++]=c;
che[flag++]='-';
first=1;
continue;
}
}
}
}
//考虑出现小数的情况
if(ch[i]=='.')
{
che[flag++]='.';
continue;
}
//考虑开头出现负数的情况,不会出现带+的正数
if(ch[i]=='-'&&i==0)
{
che[flag++]=c;
che[flag++]='-';
first=1;
continue;
}
if(Number(ch[i]))
{
if(first==0)
che[flag++]=c;
che[flag++]=ch[i];
first=1;
}
else if(Empty(S))
{
Push(S,ch[i]);
first=0;
continue;
}
else if(ch[i]==')')
{
while(Top(S)!='(')
{
che[flag++]=c;
che[flag++]=Top(S);
Pop(S);
}
Pop(S);
first=0;
continue;
}
else if(Bigger(Top(S),ch[i])&&ch[i]!='(')
{
while(!Empty(S)&&Bigger(Top(S),ch[i]))
{
che[flag++]=c;
che[flag++]=Top(S);
Pop(S);
}
Push(S,ch[i]);
first=0;
continue;
}
else
{
first=0;
Push(S,ch[i]);
}
}
while(!Empty(S))
{
che[flag++]=c;
che[flag++]=Top(S);
Pop(S);
};
for(int i=1; i<flag; i++)
{
if(che[i]=='&')
printf(" ");
else
printf("%c",che[i]);
}
return 0;
}
该题最重要的是考虑以下几种情况
序号 | 输入 | 输出 |
1 | | |
2 | | |
3 | | |
4 | | |
5 | | |
..................................................................................................................................................................................
//递归输入并创建链表
Status ListCreate_L_Rec(LinkList &L,int n)
{
//递归边界:创建空表时只需将L赋空即可;
//递归关系:创建非空表时,将链表看做两部分:首元素组成的子表La, 第二个元素及其后元素构成的子表Lb。
//子表La容易创建(只需开辟一个节点)
//子表Lb由于规模小可以递归创建完成(类似数学归纳法的假设,只要小的都可以建设能完成)
//最后将两个子表拼接即可。
LNode *La, *Lb;
if(n==0) L=NULL;
else{
La=(LNode *)malloc(sizeof(LNode)); //开辟子表La
if(!La) exit(OVERFLOW);
scanf("%d",&La->data);
ListCreate_L_Rec(Lb,n-1 ); //递归创建子表Lb
La->next = Lb; //两个子表拼结
L=La; //第一个子表的地址赋给L。请思考为什这样处理不会使得主函数中的L取错值?
}
return OK;
}
//递归输出链表
void ListPrint_L_Rec(LinkList L)
{
if(L==NULL)
{
return;
}
else
{
printf(" %d",L->data);
}
ListPrint_L_Rec(L->next);
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、