第2章-栈(2020.03.12)

第2章-栈

1. 栈的顺序实现【简单】

请用顺序存储实现栈的数据结构Stack。你所实现的栈应包括:pop,push,top,size,clear,full等功能。利用你实现的Stack实现输入数字的逆序输出。
【输入】整数序列以-1结束,序列长度小于100
【输出】输入整数序列的逆序序列
例如:
【输入】3 9 8 2 5 -1
【输出】5 2 8 9 3

(没错,这个时候我又被C++吓回去了T_T)

#include <stdio.h>

struct stack
{
    int data[105];
    int top;//top是栈顶下标
} ;

typedef struct stack mstack;

void initialize(mstack *s)
{
    s->top = -1;
}

int empty(mstack *s)
{
    if(s->top == -1)
        return 1;
    return 0;
}

int full(mstack *s)
{
    if(s->top == 105)
        return 1;
    return 0;
}

int size(mstack *s)
{
    return s->top;
}

void push(mstack *s, int x)
{
    if(full(s) == 0){
        s->top++;
        s->data[s->top] = x;
    }
}

void pop(mstack *s)
{
    if(empty(s) == 0)
        s->top--;
}

int top(mstack *s)
{
    if(empty(s) == 0)
        return s->data[s->top];
    return -1;
}

int main()
{
	mstack p;
	mstack *s = &p;
	initialize(s);
	int a;
	scanf("%d",&a);
	while(a != -1){
        push(s,a);
        scanf("%d",&a);
	}
	while(size(s) > -1)
	{
	    printf("%d ",top(s));
	    pop(s);
	}
    return 0;
}
2. 10以内的后序波兰式求解【中等】

(10以内的后序波兰式求解) 请编写程序求解10以内的后序波兰式的值。
【输入】合法的10以内的后序波兰式
【输出】后序波兰式的值(按照整型计算的结果)
例如:
【输入】23+6*
【输出】30
【输入】23+* //非法的后序表达式
【输出】none //表示无对应结果

#include <stdio.h>
#include <string.h>
#define max 100

struct stack
{
    int data[max];
    int top;
} ;

typedef struct stack mstack;
void initialize(mstack *s);
int empty(mstack *s);
int full(mstack *s);
int size(mstack *s);
void push(mstack *s, int x);
void pop(mstack *s);
int top(mstack *s);
int caculate(int a,int b,char ioperator);

int main()
{
    mstack p;
    mstack *s = &p;
    initialize(s);
    char a[81];
    scanf("%s",a);
    int num1,num2,flag=1;
    for(int i=0; i<strlen(a); i++){
        if(a[i]>='0' && a[i]<='9'){
            push(s,a[i]-'0');
            continue;
        }
        if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'){
            if(size(s) < 1){
                printf("none");//栈中少于两个数不合法
                flag=0;
                break;
            }
            num1 = top(s);
            pop(s);
            num2 = top(s);
            pop(s);
            int temp = caculate(num2,num1,a[i]);
            push(s,temp);
        }
    }
    if(size(s)>0){
        printf("none");
        flag=0;//全部运算完后栈中还有数不合法
    }
    if(flag)
        printf("%d",top(s));
    return 0;
}

void initialize(mstack *s)
{
    s->top = -1;
}

int empty(mstack *s)
{
    if(s->top == -1)
        return 1;
    return 0;
}

int full(mstack *s)
{
    if(s->top == 100)
        return 1;
    return 0;
}

int size(mstack *s)
{
    return s->top;
}

void push(mstack *s, int x)
{
    if(full(s) == 0){
        s->top++;
        s->data[s->top] = x;
    }
}

void pop(mstack *s)
{
    if(empty(s) == 0)
        s->top--;
}

int top(mstack *s)
{
    if(empty(s) == 0)
        return s->data[s->top];
    return -1;
}

int caculate(int a,int b,char ioperator)
{
    int c;
    switch(ioperator)
    {
    case '+': c = a+b; break;
    case '-': c = a-b; break;
    case '*': c = a*b; break;
    default: c = a/b; break;
    }
    return c;
}
3. 出入栈序列判断【中等】

假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,可以操作的序列称为称为合法序列,否则称为非法序列。
例如:
A.IOIIOIOO 合法 B.IOOIOIIO 不合法
C.IIIOIOIO 合法 D.IIIOOIOO 合法
请写出一个算法,判断所给的操作序列是否合法。若合法,返回true,否则返回false
【输入】n n条I和O组成的序列(序列长度<=80)
【输出】n条序列的判断结果(true或者false)
例如:
【输入】
3
IOIIOIOO
IOOIOIIO
IIIOIOIO

【输出】
true
false
true

#include <stdio.h>
#include <string.h>

int judge(char a[])
{
    int i,j,cntI,cntO;
    for(i=0; i<strlen(a); i++){
        cntI=0;
        cntO=0;
        for(j=0; j<=i; j++){
            if(a[j] == 'I'){
                cntI++;
            }
            else{
                cntO++;
            }
        }
        if(cntI < cntO)
            return 0;
    }
    return 1;
}

int main()
{
    int n,cnt=0;
    scanf("%d ",&n);
    char a[81];
	for(int i=0; i<n; i++){
        scanf("%s",a);
        (judge(a)==0)? printf("false\n"):printf("true\n");
        cnt = 0;
	}
    return 0;
}
4. 程序代码中的括号匹配【中等】

(程序代码中的括号匹配)请编写程序对一段程序代码中的括号匹配情况进行判断。括号类型有(),[],{}三类,程序代码中可能包含注释,如多行注释/**/和单行注释//,且注释内容不参与括号匹配情况的分析。
【输入】 若干行程序代码,代码长度小于1500个字符
【输出】 除去注释后的括号数量 括号是否匹配(yes/no)
例如:
【输入】
int Collatz(unsigned int n) {
if(n==1) return 0;
else if(n%2) return Collatz(n*3+1)+1;
else return Collatz(n/2)+1;
}
【输出】12 yes

【输入】
float CalcPay( /* [in] */ float payRate, // Employee’s pay rate
/
*[in] */ float hours // Hours worked
){ //return Wages earned()
【输出】 3 no

【输入】"//" ()
【输出】2 yes

#include <iostream>
#include <stdio.h>
#include <string.h>
#define max 100
using namespace std;
void dele(char a[]);

class mystack
{
public:
    mystack();
    bool Empty()const;
    void push(char item);
    void pop();
    void top(char &item)const;
private:
    int cnt;//cnt元素个数
    int entry[max];
};

int main()
{
    mystack openings;
    char str[1501];
    //输入
    int i=0;
    char temp = getchar();
    while(temp != EOF){
        str[i++] = temp;
        temp = getchar();
    }

    //去除注释
    dele(str);

    //匹配括号
    bool is_matched = true;
    int sum = 0;//括号数
    char symbol;
    for(i=0; i<strlen(str); i++){
        symbol = str[i];
        if(symbol=='{' || symbol=='[' || symbol=='('){
            openings.push(symbol);
            sum++;
           }
        if(symbol=='}' || symbol==']' || symbol==')'){
            sum++;
            //第一种情况:右括号多于左括号
            if(openings.Empty()){
                is_matched = false;
            }
            //第二种情况:进行配对
            else{
                char match;
                char &ch = match;
                openings.top(ch);//取左括号进行配对
                openings.pop();
                is_matched = (symbol=='}'&&match=='{')
                           ||(symbol==']'&&match=='[')
                           ||(symbol==')'&&match=='(');
                if(!is_matched)
                    is_matched = false;
            }
        }
    }
    //第三种情况:右括号多于左括号(遍历后栈中还有剩余)
    if(!openings.Empty())
        is_matched = false;
    if(is_matched) cout << sum << ' ' << "yes";
    else cout << sum << ' ' << "no";
    return 0;
}

mystack::mystack(){
    cnt = 0;
}

bool mystack::Empty()const
{
    bool outcome = true;
    if(cnt>0) outcome = false;
    return outcome;
}

void mystack::push(char item)
{
    if(cnt < max) entry[cnt++] = item;
}

void mystack::pop()
{
    if(cnt > 0) cnt--;
}

void mystack::top(char &item)const
{
    if(cnt > 0) item = entry[cnt-1];
}

void dele(char a[])
{
    int i;
    char *p1,*p2,*temp1,*temp2;
    for(i=0; i<strlen(a); i++){
        p1 = &a[i];
        p2 = &a[i+1];
        /*if(*p1=='"' && *p2=='/'){
            while(1){
                if(a[++i] == '\n')
                    break;
            }
            continue;
        }*/
        if(*p1 == '/'){
            if(*p2 == '/'){
                temp1 = p1;//记录注释的初始位置
                temp2 = p1+2;//进入注释
                while(1){
                    if(*temp2 == '\n')
                        break;
                    else temp2++;
                }
                memset(temp1,1,(temp2-temp1+1)*sizeof(char));
                //或把地址从temp1加到temp2挨个清零
            }
            else if(*p2 == '*'){
                temp1 = p1;//记录注释的初始位置
                temp2 = p1+2;//进入注释
                while(1){
                    if(*temp2 == '*'){
                        if(*(temp2 + 1) == '/'){
                            temp2++;
                            break;
                        }
                        else temp2++;
                    }
                    else temp2++;
                }
                memset(temp1,1,(temp2-temp1+1)*sizeof(char));
            }
            else continue;
        }
        else continue;
    }
}
5. (选做题)中序波兰式求解【困难】

(当时脆弱的我选择放弃)
(中序波兰式求解) 请编写程序求解中序波兰式的值。表达式中可能的运算符有+,-,*,/,()。
【输入】中序波兰式
【输出】波兰式的值 //输出的数据类型符合C/C++对表达式求值的定义,即表达式的输出类型由高精度的运算数来决定。

浮点型保留小数点后的3位小数
例如:
【输入】2*(4+5)-12
【输出】6
【输入】2*2.5
【输出】5.000
备注:
(1)对于80%的测试数据运算数中仅仅包含正整数;
(2)对于10%的测试数据运算数中包含有浮点数;
(3)对于10%的测试数据运算数中包含有负数;

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值