8585 栈的应用——进制转换
Description
利用顺序栈的基本操作算法,编写满足下列要求的数制转换程序:对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数。
输入格式
第一行:输入一个非负的十进制整数
输出格式
第一行:与输入等值的八进制数
输入样例
15
输出样例
17
代码实现
#include<iostream>
#include<stack>
using namespace std;
stack<int> S; //运算符栈
int main() {
int n;
cin>>n;
while(n){
S.push(n%8);
n/=8;
}
while(!S.empty()){
cout << S.top();
S.pop();
}
}
8583 顺序栈的基本操作
Description
创建一个空的顺序栈,并实现栈的入栈、出栈、返回栈的长度、返回栈顶元素、栈的遍历等基本算法。请将下面的程序补充完整。
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
// 请补全代码
}
Status Push(SqStack &S,SElemType e)
{
// 在栈S中插入元素e为新的栈顶元素
// 请补全代码
}
Status Pop(SqStack &S,SElemType &e)
{
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
// 请补全代码
}
Status GetTop(SqStack S,SElemType &e)
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
// 请补全代码
}
int StackLength(SqStack S)
{
// 返回栈S的元素个数
// 请补全代码
}
Status StackTraverse(SqStack S)
{
// 从栈顶到栈底依次输出栈中的每个元素
SElemType *p = ______________________ //请填空
if(______________________)printf("The Stack is Empty!"); //请填空
else
{
printf("The Stack is: ");
while(______________________) //请填空
{
______________________ //请填空
printf("%d ", *p);
}
}
printf("\n");
return OK;
}
int main()
{
int a;
SqStack S;
SElemType x, e;
if(______________________) // 判断顺序表是否创建成功,请填空
{
printf("A Stack Has Created.\n");
}
while(1)
{
printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
scanf("%d",&a);
switch(a)
{
case 1: scanf("%d", &x);
if(______________________) printf("Push Error!\n"); // 判断Push是否合法,请填空
else printf("The Element %d is Successfully Pushed!\n", x);
break;
case 2: if(______________________) printf("Pop Error!\n"); // 判断Pop是否合法,请填空
else printf("The Element %d is Successfully Poped!\n", e);
break;
case 3: if(______________________)printf("Get Top Error!\n"); // 判断Get Top是否合法,请填空
else printf("The Top Element is %d!\n", e);
break;
case 4: printf("The Length of the Stack is %d!\n",______________________); //请填空
break;
case 5: ______________________ //请填空
break;
case 0: return 1;
}
}
}
输入格式
测试样例格式说明:
根据菜单操作:
1、输入1,表示要实现Push操作,紧跟着输入要Push的元素
2、输入2,表示要实现Pop操作
3、输入3,返回栈顶元素
4、输入4,返回栈的元素个数
5、输入5,表示从栈顶到栈底输出栈的所有元素
6、输入0,表示程序结束
输入样例
1
2
1
4
1
6
5
3
4
2
5
2
2
2
0
输出样例
A Stack Has Created.
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 2 is Successfully Pushed!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 4 is Successfully Pushed!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 6 is Successfully Pushed!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Stack is: 6 4 2
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Top Element is 6!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Length of the Stack is 3!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 6 is Successfully Poped!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Stack is: 4 2
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 4 is Successfully Poped!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
The Element 2 is Successfully Poped!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
Pop Error!
1:Push
2:Pop
3:Get the Top
4:Return the Length of the Stack
5:Load the Stack
0:Exit
Please choose:
代码实现
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
struct SqStack {
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S) {
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
S.base = new SElemType[STACK_INIT_SIZE];
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S, SElemType e) {
// 在栈S中插入元素e为新的栈顶元素
if(S.top-S.base==S.stacksize)return ERROR;
*S.top++=e;
return OK;
}
Status Pop(SqStack &S, SElemType &e) {
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
// 请补全代码
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
Status GetTop(SqStack S, SElemType &e) {
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
// 请补全代码
if(S.top==S.base)return ERROR;
e= *(S.top-1);
return OK;
}
int StackLength(SqStack S) {
// 返回栈S的元素个数
return S.top-S.base;
// 请补全代码
}
Status StackTraverse(SqStack S) {
// 从栈顶到栈底依次输出栈中的每个元素
SElemType *p=S.top; //请填空
if (StackLength(S)==0)printf("The Stack is Empty!"); //请填空
else {
printf("The Stack is: ");
while (p>S.base) //请填空
{//请填空
p--;
printf("%d ", *p);
}
}
printf("\n");
return OK;
}
int main() {
int a;
SqStack S;
SElemType x, e;
if (InitStack(S)) // 判断顺序表是否创建成功,请填空
{
printf("A Stack Has Created.\n");
}
while (1) {
printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
scanf("%d", &a);
switch (a) {
case 1:
scanf("%d", &x);
if (!Push(S, x)) printf("Push Error!\n"); // 判断Push是否合法,请填空
else printf("The Element %d is Successfully Pushed!\n", x);
break;
case 2:
if (!Pop(S, e)) printf("Pop Error!\n"); // 判断Pop是否合法,请填空
else printf("The Element %d is Successfully Poped!\n", e);
break;
case 3:
if (!GetTop(S, e))printf("Get Top Error!\n"); // 判断Get Top是否合法,请填空
else printf("The Top Element is %d!\n", e);
break;
case 4:
printf("The Length of the Stack is %d!\n", StackLength(S)); //请填空
break;
case 5:
StackTraverse(S); //请填空
break;
case 0:
return 1;
}
}
}
8584 循环队列的基本操作
Description
创建一个空的循环队列,并实现入队、出队、返回队列的长度、返回队头元素、队列的遍历等基本算法。请将下面的程序补充完整。
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int QElemType;
#define MAXQSIZE 100 // 最大队列长度(对于循环队列,最大队列长度要减1)
typedef struct
{
QElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
Status InitQueue(SqQueue &Q)
{
// 构造一个空队列Q,该队列预定义大小为MAXQSIZE
// 请补全代码
}
Status EnQueue(SqQueue &Q,QElemType e)
{
// 插入元素e为Q的新的队尾元素
// 请补全代码
}
Status DeQueue(SqQueue &Q, QElemType &e)
{
// 若队列不空, 则删除Q的队头元素, 用e返回其值, 并返回OK; 否则返回ERROR
// 请补全代码
}
Status GetHead(SqQueue Q, QElemType &e)
{
// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR
// 请补全代码
}
int QueueLength(SqQueue Q)
{
// 返回Q的元素个数
// 请补全代码
}
Status QueueTraverse(SqQueue Q)
{
// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
int i;
i=Q.front;
if(______________________)printf("The Queue is Empty!"); //请填空
else{
printf("The Queue is: ");
while(______________________) //请填空
{
printf("%d ",______________________ ); //请填空
i = ______________________; //请填空
}
}
printf("\n");
return OK;
}
int main()
{
int a;
SqQueue S;
QElemType x, e;
if(______________________) // 判断顺序表是否创建成功,请填空
{
printf("A Queue Has Created.\n");
}
while(1)
{
printf("1:Enter \n2:Delete \n3:Get the Front \n4:Return the Length of the Queue\n5:Load the Queue\n0:Exit\nPlease choose:\n");
scanf("%d",&a);
switch(a)
{
case 1: scanf("%d", &x);
if(______________________) printf("Enter Error!\n"); // 判断入队是否合法,请填空
else printf("The Element %d is Successfully Entered!\n", x);
break;
case 2: if(______________________) printf("Delete Error!\n"); // 判断出队是否合法,请填空
else printf("The Element %d is Successfully Deleted!\n", e);
break;
case 3: if(______________________)printf("Get Head Error!\n"); // 判断Get Head是否合法,请填空
else printf("The Head of the Queue is %d!\n", e);
break;
case 4: printf("The Length of the Queue is %d!\n",______________________); //请填空
break;
case 5: ______________________ //请填空
break;
case 0: return 1;
}
}
}
输入格式
测试样例格式说明:
根据菜单操作:
1、输入1,表示要实现入队操作,紧跟着输入要入队的元素
2、输入2,表示要实现出队操作
3、输入3,返回队头元素
4、输入4,返回队列的元素个数
5、输入5,表示从队头到队尾输出队的所有元素
6、输入0,表示程序结束
输入样例
1
1
1
2
1
3
5
2
3
5
0
输出样例
A Queue Has Created.
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Element 1 is Successfully Entered!
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Element 2 is Successfully Entered!
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Element 3 is Successfully Entered!
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Queue is: 1 2 3
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Element 1 is Successfully Deleted!
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Head of the Queue is 2!
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
The Queue is: 2 3
1:Enter
2:Delete
3:Get the Front
4:Return the Length of the Queue
5:Load the Queue
0:Exit
Please choose:
代码实现
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int QElemType;
#define MAXQSIZE 100 // 最大队列长度(对于循环队列,最大队列长度要减1)
typedef struct {
QElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;
Status InitQueue(SqQueue &Q) {
// 构造一个空队列Q,该队列预定义大小为MAXQSIZE
Q.base = new QElemType[MAXQSIZE];
Q.front = Q.rear = 0;
return OK;
}
Status EnQueue(SqQueue &Q, QElemType e) {
// 插入元素e为Q的新的队尾元素
if(Q.rear+1%MAXQSIZE==Q.front)return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q, QElemType &e) {
// 若队列不空, 则删除Q的队头元素, 用e返回其值, 并返回OK; 否则返回ERROR
if(Q.front==Q.rear)return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
Status GetHead(SqQueue Q, QElemType &e) {
// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR
if(Q.front==Q.rear)return ERROR;
e=Q.base[Q.front];
return OK;
}
int QueueLength(SqQueue Q) {
// 返回Q的元素个数
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
Status QueueTraverse(SqQueue Q) {
// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
int i;
i = Q.front;
if (QueueLength(Q)==0)printf("The Queue is Empty!"); //请填空
else {
printf("The Queue is: ");
while (i!=Q.rear) //请填空
{
printf("%d ", Q.base[i]); //请填空
i = (i+1)%MAXQSIZE; //请填空
}
}
printf("\n");
return OK;
}
int main() {
int a;
SqQueue S;
QElemType x, e;
if (InitQueue(S)) // 判断顺序表是否创建成功,请填空
{
printf("A Queue Has Created.\n");
}
while (1) {
printf("1:Enter \n2:Delete \n3:Get the Front \n4:Return the Length of the Queue\n5:Load the Queue\n0:Exit\nPlease choose:\n");
scanf("%d", &a);
switch (a) {
case 1:
scanf("%d", &x);
if (!EnQueue(S,x)) printf("Enter Error!\n"); // 判断入队是否合法,请填空
else printf("The Element %d is Successfully Entered!\n", x);
break;
case 2:
if (!DeQueue(S,e)) printf("Delete Error!\n"); // 判断出队是否合法,请填空
else printf("The Element %d is Successfully Deleted!\n", e);
break;
case 3:
if (!GetHead(S,e))printf("Get Head Error!\n"); // 判断Get Head是否合法,请填空
else printf("The Head of the Queue is %d!\n", e);
break;
case 4:
printf("The Length of the Queue is %d!\n", QueueLength(S)); //请填空
break;
case 5:
QueueTraverse(S); //请填空
break;
case 0:
return 1;
}
}
}
8588 表达式求值
Description
顺序栈的基本操作如下:
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) return ERROR;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S,SElemType e)
{
// 在栈S中插入元素e为新的栈顶元素
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) return ERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
Status Pop(SqStack &S,SElemType &e)
{
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
Status GetTop(SqStack S,SElemType &e)
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
e=*(S.top-1);
return OK;
}
int StackLength(SqStack S)
{
// 返回栈S的元素个数
int i;
i=S.top-S.base;
return i;
}
Status StackTraverse(SqStack S)
{
// 从栈顶到栈底依次输出栈中的每个元素
SElemType *p = (SElemType *)malloc(sizeof(SElemType));
p = S.top;
if(S.top==S.base)printf("The Stack is Empty!");
else
{
printf("The Stack is: ");
p--;
while(p>=S.base)
{
printf("%d ", *p);
p--;
}
}
printf("\n");
return OK;
}
利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要求输出表达式的值(两运算符号的优先关系见教材表3.1)。
输入格式
第一行:一个算术表达式
输出格式
第一行:算术表达式的值
输入样例
3*(9-7)=
输出样例
6
代码实现
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<char> OPTR; //运算符栈
stack<double> OPND; //操作数栈
int getIndex(char theta) //获取运算符在矩阵中对应的索引
{
switch (theta) {
case '+':
return 0;
case '-':
return 1;
case '*':
return 2;
case '/':
return 3;
case '(':
return 4;
case ')':
return 5;
case '#':
return 6;//等效
case '=':
return 6;
}
return -1;
}
char Precede(char theta1, char theta2) //获取theta1与theta2之间的优先级
{
const char priority[][7] = //算符间的优先级关系
{ // + - * / ( ) =
{'>', '>', '<', '<', '<', '>', '>'},//+
{'>', '>', '<', '<', '<', '>', '>'},//-
{'>', '>', '>', '>', '<', '>', '>'},//*
{'>', '>', '>', '>', '<', '>', '>'},///
{'<', '<', '<', '<', '<', '=', '0'},//(
{'>', '>', '>', '>', '0', '>', '>'},//)
{'<', '<', '<', '<', '<', '0', '='},//#
};
int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
double Operate(double b, char theta, double a) {
switch (theta) {
case '+':
return b + a;
case '-':
return b - a;
case '*':
return b * a;
case '/':
return b / a;
}
return -1;
}
double evaluateExpression() //表达式求值
{
OPTR.push('#'); //首先将'#'入OPTR
bool preIsDigit; //上一位是否为数字
char c;
cin >> c;
while (c != '=' || OPTR.top() != '#') {
if (isdigit(c)) //如果不是操作符
{
//多位数字
if (preIsDigit) {
double t = OPND.top();//取出上位数字
OPND.pop();
OPND.push(t * 10 + (c - '0'));//与本位进位
preIsDigit = true;
}
//单位数字
else {
OPND.push(c - '0');
preIsDigit = true;
}
c = getchar();
}
//不是数字
else {
preIsDigit = false;
switch (Precede(OPTR.top(), c)) {
case '<':
OPTR.push(c);
cin >> c;
break;
case '=':
OPTR.pop();//抛弃左括号
cin >> c;
break;
case '>':
//取运算符
char theta = OPTR.top();
OPTR.pop();
//取二元
double a = OPND.top();
OPND.pop();
double b = OPND.top();
OPND.pop();
//运算
OPND.push(Operate(b, theta, a));
}
}
}
return OPND.top();
}
int main() {
cout << evaluateExpression();
return 0;
}
刚开始使用题目提供的操作函数提交不成功,猜测是有结果为2位数的表达式结果,后改用
stack
库,并将运算符栈
元素设为char
类型,数值栈
元素设为double
类型
8587 行编辑程序
Description
利用栈编写简单的行编辑程序:接受用户从终端输入的程序或数据,在输入过程中,允许用户输入出差错,并在发现有误时可以及时更正。例如:当用户发现刚刚键入的一个字符是错的时,可以补进一个退格符“#”,以表示前一个字符无效;如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符“@”,以表示当前行中的字符均无效。例如:假设从终端接受了这样两行字符: whli##ilr#e (s#*s) outcha@putchar(*s=#++); 则实际有效的是下列两行: while (*s) putchar(*s++); 本题目给出部分函数,要求将行编辑函数补充完整,并完成整个程序。
typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{ // 构造一个空栈S
}
Status StackEmpty(SqStack S)
{ // 若栈S为空栈,则返回TRUE,否则返回FALSE
}
Status ClearStack(SqStack &S)
{ // 把S置为空栈
S.top=S.base;
return OK;
}
Status DestroyStack(SqStack &S)
{ // 销毁栈S,S不再存在
free(S.base);
S.base=NULL;
S.top=NULL;
S.stacksize=0;
return OK;
}
Status Push(SqStack &S,SElemType e)
{ // 插入元素e为新的栈顶元素
}
Status Pop(SqStack &S,SElemType &e)
{ // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
}
Status StackTraverse(SqStack S,Status(*visit)(SElemType))
{ // 从栈底到栈顶依次对栈中每个元素调用函数visit()。
// 一旦visit()失败,则操作失败
while(S.top>S.base)
visit(*S.base++);
printf("\n");
return OK;
}
Status visit(SElemType c)
{
printf("%c",c);
return OK;
}
void LineEdit()
{ // 利用字符栈s,从终端接收一行并送至调用过程的数据区。算法3.2
SqStack s;
char ch,c;
int n,i;
InitStack(s);
scanf("%d",&n);
ch=getchar();
for(i=1;i<=n;i++)
{ ch=_______________________________;
while(ch!='\n')
{
switch(_____________________)
{
case '#':Pop(s,c);
break; // 仅当栈非空时退栈
case '@':ClearStack(s);
break; // 重置s为空栈
default :_________________________________; // 有效字符进栈
}
____________________________; // 从终端接收下一个字符
}
StackTraverse(s,visit); // 将从栈底到栈顶的栈内字符输出
_____________________________________; // 重置s为空栈
}
DestroyStack(s);
}
void main()
{
LineEdit();
}
输入格式
第一行:第一个字符为输入文本的行数n;
第二行至第n行:每行均为一串字符,其间可以含有“#”和“@”符号,以回车键结束本行的输入;
输出格式
输出第一至第n行的内容如下:
第一行:第一行从终端输入的有效字符。
第二行:第二行从终端输入的有效字符。
…… ……
第n行:第n行从终端输入的有效字符。
输入样例
2
defne##ine OK 1
typp cila@type int element
输出样例
define OK 1
type int element
代码实现【偷懒版】
typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 100 // 存储空间初始分配量【偷懒了】
#define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack {
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S) { // 构造一个空栈S
S.base = new SElemType[STACK_INIT_SIZE];
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status StackEmpty(SqStack S) { // 若栈S为空栈,则返回TRUE,否则返回FALSE
return(S.top==S.base);
}
Status ClearStack(SqStack &S) { // 把S置为空栈
S.top = S.base;
return OK;
}
Status DestroyStack(SqStack &S) { // 销毁栈S,S不再存在
free(S.base);
S.base = NULL;
S.top = NULL;
S.stacksize = 0;
return OK;
}
//【偷懒了】
Status Push(SqStack &S, SElemType e) { // 插入元素e为新的栈顶元素
if(S.top-S.base==S.stacksize)return ERROR;
*S.top++=e;
return OK;
}
Status Pop(SqStack &S, SElemType &e) { // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
Status StackTraverse(SqStack S, Status(*visit)(SElemType)) { // 从栈底到栈顶依次对栈中每个元素调用函数visit()。
// 一旦visit()失败,则操作失败
while (S.top > S.base)
visit(*S.base++);
printf("\n");
return OK;
}
Status visit(SElemType c) {
printf("%c", c);
return OK;
}
void LineEdit() { // 利用字符栈s,从终端接收一行并送至调用过程的数据区。算法3.2
SqStack s;
char ch, c;
int n, i;
InitStack(s);
scanf("%d", &n);
ch = getchar();
for (i = 1; i <= n; i++) {
ch = getchar();
while (ch != '\n') {
switch (ch) {
case '#':
if(!StackEmpty(s))Pop(s, c);
break; // 仅当栈非空时退栈
case '@':
ClearStack(s);
break; // 重置s为空栈
default :
Push(s, ch); // 有效字符进栈
}
ch = getchar();; // 从终端接收下一个字符
}
StackTraverse(s, visit); // 将从栈底到栈顶的栈内字符输出
ClearStack(s); // 重置s为空栈
}
DestroyStack(s);
}
int main() {
LineEdit();
}
附加:填空版Push函数,没有修改STACK_INIT_SIZE进行偷懒,之前主要考虑到是realloc()
在C++中已被摒弃,就没有继续使用了,感谢焦糖抱猪奶茶
指出。
Status Push(SqStack &S, SElemType e) { // 插入元素e为新的栈顶元素
//如果超出范围,申请更大的空间
if (S.top - S.base >= S.stacksize) {
//C++中已经摒弃realloc函数,若要实现类似功能,应用new新建一个空间再拷贝数据过去,有点麻烦,就不做了
S.base = (SElemType *) realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S.base) return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}
8586 括号匹配检验
Description
利用栈编写满足下列要求的括号匹配检验程序:假设表达式中允许包含两种括号:圆括号和方括号,其嵌套的顺序随意,即()或[([][])]等为正确的格式,[(]或([())或(()])均为不正确的格式。输入一个包含上述括号的表达式,检验括号是否配对。本题给出部分check()函数,要求将check()函数补充完整,并完成整个程序。
typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{
}
Status StackEmpty(SqStack S)
{
}
Status Push(SqStack &S,SElemType e)
{
}
Status Pop(SqStack &S,SElemType &e)
{
}
void check()
{ // 对于输入的任意一个字符串,检验括号是否配对
SqStack s;
SElemType ch[80],*p,e;
if(InitStack(s)) // 初始化栈成功
{
//printf("请输入表达式\n");
__________________________________;
p=ch;
while(*p) // 没到串尾
switch(*p)
{
case '(':
case '[':_______________________;
break; // 左括号入栈,且p++
case ')':
case ']':if(!StackEmpty(s)) // 栈不空
{
_________________________; // 弹出栈顶元素
if(*p==')'&&e!='('||___________________&&___________________)
// 弹出的栈顶元素与*p不配对
{
printf("isn't matched pairs\n");
exit(ERROR);
}
else
{
__________________________;
break; // 跳出switch语句
}
}
else // 栈空
{
printf("lack of left parenthesis\n");
exit(ERROR);
}
default: ______________________; // 其它字符不处理,指针向后移
}
if(StackEmpty(s)) // 字符串结束时栈空
printf("matching\n");
else
printf("lack of right parenthesis\n");
}
}
int main()
{
check();
}
输入格式
第一行:输入一个包含圆括号或方括号、不超过80个字符的表达式串。
输出格式
第一行:若输入表达式括号匹配,输出"matching"; 若不匹配,输出具体信息:“isn’t matched pairs”, 或"lack of left parenthesis"或"lack of right parenthesis"
输入样例
8*[3*(35-23)]
输出样例
matching
代码实现
typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack {
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status StackEmpty(SqStack S) {
return (S.base == S.top);
}
Status InitStack(SqStack &S) {
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
S.base = new SElemType[STACK_INIT_SIZE];
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S, SElemType e) {
// 在栈S中插入元素e为新的栈顶元素
if (S.top - S.base == S.stacksize)return ERROR;
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S, SElemType &e) {
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
// 请补全代码
if (S.top == S.base)return ERROR;
e = *--S.top;
return OK;
}
void check() { // 对于输入的任意一个字符串,检验括号是否配对
SqStack s;
SElemType ch[80], *p, e;
if (InitStack(s)) // 初始化栈成功
{
//printf("请输入表达式\n");
gets(ch);
p = ch;
while (*p) // 没到串尾
switch (*p) {
case '(':
case '[':
Push(s, *p++);
break; // 左括号入栈,且p++
case ')':
case ']':
if (!StackEmpty(s)) // 栈不空
{
Pop(s, e); // 弹出栈顶元素
if (*p == ')' && e != '(' || *p == ']' && e != '[')
// 弹出的栈顶元素与*p不配对
{
printf("isn't matched pairs\n");
exit(ERROR);
} else {
p++;
break; // 跳出switch语句
}
} else // 栈空
{
printf("lack of left parenthesis\n");
exit(ERROR);
}
default:
p++;; // 其它字符不处理,指针向后移
}
if (StackEmpty(s)) //字符串结束时栈空
printf("matching\n");
else
printf("lack of right parenthesis\n");
}
}
int main() {
check();
}
18938 汉诺塔问题
Description
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以64个盘的移动次数是:18,446,744,073,709,551,615
这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。
我们仅能找出问题的解决方法并解决较小N值时的汉诺塔,但很难用计算机解决64层的汉诺塔。
假定圆盘从小到大编号为1, 2, …
输入格式
输入为一个整数(小于20)后面跟三个单字符字符串。
整数为盘子的数目,后三个字符表示三个杆子的编号。
输出格式
输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如 a->3->b 的形式,即把编号为3的盘子从a杆移至b杆。
输入样例
2 a b c
输出样例
a->1->c
a->2->b
c->1->b
代码实现
#include <iostream>
using namespace std;
void printStep(int code, char x, char y) {
cout << x << "->" << code << "->" << y << "\n";
}
void Step(int n, char now, char after, char tmp) {
if (n == 1)printStep(n, now, after);
else{
Step(n-1, now, tmp, after);
printStep(n, now, after);
Step(n-1, tmp, after, now);
}
}
int main() {
int num;
char now,after,tmp;
scanf("%d %c %c %c",&num,&now,&after,&tmp);
Step(num,now,after,tmp);
return 0;
}