c++实验4 栈及栈的应用+回文+中、后缀表达式

栈及栈的应用+回文+中、后缀表达式

1、栈顺序存储结构的基本操作算法实现

(1)栈顺序存储结构的类定义:

class SeqStack
{
private:
    int maxsize;
    DataType *data;      //顺序堆栈数组
    int top;                                            //栈顶位置指示器
public:
    SeqStack(int size);      //构造函数
    ~SeqStack(void) {}            //析构函数
    void Push(const DataType item);      //入栈
    DataType Pop(void);                  //出栈
    DataType GetTop(void)const;      //取栈顶数据元素
    void GetAll();
    void Destory();
    void ClearAll();
    int NotEmpty(void)const            //堆栈空否
    {return(top==-1);};
    int Full(void)const             //堆栈满否
    {return(top==maxsize-1);};
};

(2)构造栈算法

输入:栈元素个数的最大数size

初始化栈:栈顶指示置为-1,创建存储栈的数组,栈元素个数的最大数maxsize置 为size;

SeqStack::SeqStack(int size)
{
    top=-1;
    maxsize=size;
    data=new DataType[maxsize];
}

(3)获得栈顶元素算法

输入:无

前置条件:栈不空

动作:取栈顶数据元素给e

输出:返回栈顶元素值e

后置条件:无

DataType SeqStack::GetTop(void)const           //取栈顶数据元素
//取当前栈顶数据元素并返回
{
    if(top==-1)
    {
        cout<<"堆栈空!"<<endl;
        exit(0);
    }
    DataType e=data[top-1];
    return e;                        //返回当前栈顶元素
}

(4)进栈算法

输入:要进栈的项item

前置条件:栈未满

动作:把item压入栈顶

输出:无

后置条件:栈顶增加一个新元素,栈顶指示加1;

void SeqStack::Push(const DataType item)       //入栈
//把元素item入栈;堆栈满时出错退出
{
    if(top==maxsize)
    {
        cout<<"堆栈已满!"<<endl;
        exit(0);
    }
    data[top]=item;                       //先存储item
    top++;                                //然后top加1
}

(5)出栈算法

输入:无

前置条件:栈非空

动作:删除栈顶元素

输出:返回删除的栈顶元素值

后置条件:删除栈顶元素,栈顶指示减1

DataType SeqStack::Pop()                       //出栈
//出栈并返回栈顶元素;堆栈空时出错退出
{
    if(top==-1)
    {
        cout<<"堆栈已空!"<<endl;
        exit(0);
    }
    top--;                             //top先减1
    return data[top];                 //然后取元素返回
}

(6)遍历栈算法

输入:无

前置条件:栈非空

动作:遍历输出每个栈非空元素

输出:无

后置条件:无

void SeqStack::GetAll()
{
    if(top==-1)
    {
        cout<<"堆栈已空!"<<endl;
        exit(0);
    }
    for(int i=top-1;i>=-1;i--)
    {
        cout<<data[i]<<" ";
    }
    cout<<endl;
}

(7)销毁栈算法

输入:无

前置条件:栈存在

动作:删除存储栈元素的数组

输出:无

后置条件:栈的存储元素区域不存在,栈顶指针归-1,maxsize为0

void SeqStack::Destory()
{
    top=-1;

    delete data;
    cout<<"栈的存储元素区域不存在"<<endl;
    maxsize=0;
}

(8)清空栈算法

输入:无

前置条件: 无

动作:清空栈,栈顶指示器归-1;

输出:无

后置条件:栈顶指示为-1

void SeqStack::ClearAll()
{
    top=-1;
}

上机实现以上基本操作,写出main()程序:

#include <iostream>
typedef int DataType;
#include"SeqStack.h"
using namespace std;
int main()
{
    SeqStack stack1335(10);
    DataType test[]={2,4,6,8,10};
    for(int i=0;i<5;i++)
        stack1335.Push(test[i]);
     cout<<"入栈"<<endl;
    while(!stack1335.NotEmpty())
        cout<<stack1335.Pop()<<" ";
    cout<<"出栈"<<endl;
    for(int i=0;i<5;i++)
        stack1335.Push(test[i]);
    cout<<"入栈"<<endl;
    stack1335.ClearAll();
    cout<<"清空所有"<<endl;
    stack1335.GetAll();
    return 0;
}

2、用以上基本算法,实现:void conversion()

将输入10进制数转化为2进制和8进制数

void SeqStack::conversion(int num)
{
    int a=num;
    while(a)
    {
        Push(a%2);
        a/=2;
    }
    cout<<"转换为二进制:";
    GetAll();
    ClearAll();
    while(num)
    {
        Push(num%8);
        num/=8;
    }
     cout<<"转换为八进制:";
     GetAll();
  }
} 

3、回文是指正读反读均相同的字符序列,如“acdca”、“dceecd”均是回文,但“book”不是回文。利用1中的基本算法,试写一个算法判定给定的字符串是否为回文。(提示:将一半字符入栈,依次弹出与另一半逐个比较)//判s串是否为回文,是则返回1,否则返回0;

int SeqStack::HuiWen(char *s)
{
    int i,j;
    for(i=0;s[i]!=‘\0‘;i++);
    for(j=0;j<(i-1)/2;j++)
    {
        Push(s[j]);
    }
    char ch= Pop();
    if(s[j]==ch)
    {
        for(int k=j;k<i-1;i++)
        {
            if(s[k]!=Pop())
                return 0;
        }
        return 1;
    }

    else if(s[j+1]==ch)
    {
        for(int k=j+2;k<i-1;k++)
        {
            if(s[k]!=Pop())
                return 0;
        }
        return 1;

     }
     else
        return 0;
}
int main()
{
    SeqStack stack1335(10);
    char b[7]={‘a‘,‘b‘,‘s‘,‘c‘,‘s‘,‘b‘,‘a‘};
cout<<"给定字符串:"<<b<<"是否是回文?(1-是/2-否)"<<stack1335.HuiWen(b)<<endl;
}

4、实现栈的链式操作算法。

#include<stdlib.h>
#include<iostream>
using namespace std;
template<class T>
class LinStack;
template <class T>
class StackNode
{
    friend class LinStack<T>;
private:
    T data;
    StackNode<T> *next;
public:
    StackNode(StackNode<T> *ptrNext=NULL)
    {next=ptrNext;}
    StackNode(const T& item,StackNode<T> *ptrNext=NULL)
    {data=item;next=ptrNext;}
    ~StackNode(){}
};
template<class T>
class LinStack
{
private:
    StackNode<T>*head;
    int size;
public:
    LinStack(void);                           //构造函数
    ~LinStack(void);                          //析构函数
    void Push(const T& item);           //入栈
    T Pop(void);                                   //出栈
    T GetTop(void) const;                  //取栈顶元素
    int NotEmpty(void) const;             //堆栈非空否
};
template <class T>
LinStack <T>::LinStack()                    //构造函数
{
    head=new StackNode <T>;                 //头指针指向头结点
    size=0;                                 //size的初值为0
}
template <class T>
LinStack <T>::~LinStack(void)               //析构函数
//释放所有动态申请的结点空间
{
    StackNode <T> *p,*q;
    p=head;                                 //p指向头结点
    while(p!=NULL)                          //循环释放结点空间
    {
        q=p;
        p=p->next;
        delete q;
    }
}
template <class T>
int LinStack <T>::NotEmpty(void) const      //堆栈非空否
{
    if(size!=0)
        return 1;
    else
        return 0;
}
template <class T>
void LinStack <T>::Push(const T& item)      //入栈
{
    //新结点newNode的data域值为item,next域值为head->next
    StackNode <T> *newNode=new StackNode <T> (item,head->next);
    head->next=newNode;                    //新结点插入栈顶
    size++;                                //元素个数加1
}
template <class T>
T LinStack <T>::Pop(void)                  //出栈
{   if(size==0)
    {
        cout<<"堆栈已空无元素可删!"<<endl;
        exit(0);
    }
    StackNode <T> *p=head->next;       //p指向栈顶元素结点
    T data=p->data;
    head->next=head->next->next;       //原栈顶元素结点脱链
    delete p;                          //释放原栈顶结点空间
    size--;                            //结点个数减1
    return data;                   //返回原栈顶结点的data域值
}
template <class T>
T LinStack <T>::GetTop(void) const         //取栈顶元素
{
    return head->next->data;
}

测试数据(main函数)

#include <iostream>
#include"LinStack.h"
using namespace std;

int main()
{
    int n[]={1,2,3,4,5,6,7,8,9,0};
    LinStack<int>li;
    cout<<"入栈元素:";
    for(int i=0;i<10;i++)
    {
        cout<<n[i]<<" ";
        li.Push(n[i]);
    }
    cout<<"\n当前栈顶元素:"<<li.GetTop()<<endl;;
    cout<<"是否非空(1-非空,0-空)"<<li.NotEmpty()<<endl;
    cout<<"出栈一个顶部元素:"<<li.Pop()<<endl;;
    cout<<"当前栈顶元素:"<<li.GetTop()<<endl;;
    return 0;
}

5、实现后缀表达式求值Eval(postexp e)算法。

#include <iostream>
#include<ctype.h>
#include<stdlib.h>
#include"LinStack.h"
template <class T>
void PostExp(LinStack <T> &s)
{
    char ch;           //ch为char类型变量
    T x,x1,x2;
    cout<<"输入后缀表达式(表达式以#符号结束):";
    while(cin>>ch&&ch!=‘#‘)   //循环直到输入为‘#‘
    {
        if(isdigit(ch))       //ch为数字类型
        {
            cin.putback(ch);  //回退一位
            cin>>x;           //按数值类型重新输入
            s.Push(x);        //x入栈
        }
        else
        {
            x2=s.Pop();       //退栈得操作数
            x1=s.Pop();       //退栈得被操作数
            switch(ch)
            {
            case‘+‘:{x1+=x2;break;}
            case‘-‘:{x1-=x2;break;}
            case‘*‘:{x1*=x2;break;}
            case‘/‘:
                if(x2==0.0)
                {
                    cout<<"除数为0错!";
                    exit(0);
                }
                else
                {
                    x1/=x2;
                    break;
                }
            }
             s.Push(x1);        //运算结果入栈
          }
    }
    cout<<"后缀表达式计算结果为:"<<s.Pop()<<endl;
}
using namespace std;
int main()
{

    LinStack<int>li;
   PostExp(li);
}

6、实现中缀表达式转换成后缀表达式postfix(expression e)算法

void error()
{
     cout<<"输入有误 退出"<<endl;
     exit(0);
}
template <class T>
int PostFix(LinStack <T> &s)
{
    string a,b;
    char ch;           //ch为char类型变量
    T x1,x2=‘ ‘;
    s.Push(‘#‘);
    cout<<"输入中缀表达式(表达式以#符号结束):";
    int flag=1;
    while(true)   //循环直到输入为‘#‘
    {
        if(x2!=‘#‘&&flag==1)
        {
            b+=ch;
            cin>>ch;
        }
        if(!isdigit(ch))       //ch不为数字类型
        {
            x1=s.GetTop();
            x2=ch;
            if(x2==‘)‘)
                flag=0;
            if(x1==‘+‘||x1==‘-‘)
            {
                if(x2==‘+‘||x2==‘-‘||x2==‘)‘||x2==‘#‘)
                {
                    a+=s.Pop();
                }
                else if(x2==‘*‘||x2==‘/‘||x2==‘(‘)
                    s.Push(x2);
                else
                    error();
            }
             if(x1==‘*‘||x1==‘/‘)
            {
                if(x2==‘+‘||x2==‘-‘||x2==‘)‘||x2==‘#‘||x2==‘*‘||x2==‘/‘)
                     a+=s.Pop();
                else if(x2==‘(‘)
                    s.Push(x2);
                else
                    error();
            }
            if(x1==‘(‘)
            {
                if(x2==‘)‘)
                {
                    s.Pop();
                    flag=1;
                }

                else if(x2==‘+‘||x2==‘-‘||x2==‘*‘||x2==‘/‘||x2==‘(‘)
                    s.Push(x2);
                 else
                     error();
            }
             if(x1==‘)‘)
            {
                if(x2==‘+‘||x2==‘-‘||x2==‘*‘||x2==‘/‘||x2==‘)‘||x2==‘#‘)
                    a+=s.Pop();
                 else
                     error();

            }
             if(x1==‘#‘)
            {
                if(x2==‘+‘||x2==‘-‘||x2==‘*‘||x2==‘/‘||x2==‘(‘)
                {
                    s.Push(x2);
                }
                else if(x2==‘#‘)
                {
                    cout<<"中缀表达式为:"<<b<<"\n后缀表达式为:"<<a<<endl;
                    return 0;
                }
                else
                     error();
            }
        }
        else                    //ch是数字
        {
            a+=ch;
        }
    }
}

测试函数(main函数)

主函数
int main()
{

    LinStack<int>li;
   PostFix(li);
}

原文地址:https://www.cnblogs.com/cc123nice/p/10630014.html

时间: 2024-10-16 09:51:04

c++实验4 栈及栈的应用+回文+中、后缀表达式的相关文章

DS之顺序栈和链队实现回文判断

顺序栈和链队的基本操作就不再一一列举了,要想实现回文判断,先来了解什么是回文?"回文"一字符串正着读和反着读是相同的字符序列,如"abcba","abba"为"回文","abab"则不是"回文". 其次就是顺序栈和链队如何实现回文的判断?将输入的字符串依次入栈和入队,然后再依次出栈和出队,由于入栈和入队是相同的序列,然而出栈和出队是相反的序列,这就实现了回文的判断. 最后考虑要用到顺序栈

栈应用 - 后缀表达式的计算

有关栈API详情參看我的还有一篇博文:栈的链式存储 - API实现 遍历后缀表达式中的数字和符号 对于数字:进栈 对于符号: 从栈中弹出右操作数 从栈中弹出左操作数 依据符号进行运算 将运算结果压入栈中 遍历结束:栈中的唯一数字为计算结果 #include <stdio.h> #include "LinkStack.h" int isNumber3(char c) { return ('0' <= c) && (c <= '9'); } int

【栈】洛谷P1449 后缀表达式

#include <iostream> #include <stack> using namespace std; int main(){ stack<int>s; char t; while(cin>>t && t != '@'){ //输入字符串t 当为@时结束 if( t>='0' && t<='9'){ //如果t是数字 int a = t - '0'; //那么先把t赋值给a while(cin>&

08.栈(二)栈的应用

一.栈的应用-递归 1.递归函数:把一个直接调用自己或通过一系列的调用语句间接地调用自己的函数,称为递归函数. 2.栈与递归 递归函数实际是一个前行和退回的过程,相当与入栈.出栈.在前行阶段,对于每一层递归,函数的局部变量.参数值以及返回地址都被压入栈中.在退回阶段,位于栈顶的局部变量.参数值和返回地址被弹出(出栈),用于返回调用层次中执行代码的其余部分,也就是恢复了调用的状态. 3.递归应用-斐波那契数列 斐波那契数列描述的是兔子的繁殖问题,这个数列有个十分明显的特点:前面相邻两项之和,构成了

Python与数据结构[1] -&gt; 栈/Stack[1] -&gt; 中缀表达式与后缀表达式的转换和计算

中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操作数(数字/字母等),则加入后缀表达式中 若元素为操作符,则压入栈中,此时对比入栈操作符与栈内元素的计算等级,等级大于或等于入栈元素的栈内操作符都将被弹出栈,加入到后缀表达式中 左括号直接入栈,优先级最高,不弹出栈内元素 右括号不入栈,而是弹出所有元素加入后缀表达式,直至遇见匹配的左括号,并弹出左括

Java实验--关于简单字符串回文的递归判断实验

首先题目要求写的是递归的实验,一开始没注意要求,写了非递归的方法.浪费了一些时间,所谓吃一堑长一智.我学习到了以后看实验的时候要认真看实验中的要求,防止再看错. 以下是对此次的实验进行的分析: 1)递归是运用到了栈的思想 2)回文是一段从中间开始倒置的文字,回代的过程中出现不同的符号的时候就说明这段文字不是回文了 根据上面对回文判断的分析,就拿最简单的121来说,要每个字符判断直至2所在的位置,然后依次回代判断前面的1和后面的1的位置(上述的描述就类似于栈的思想). 有关于栈还有递归其实我并不熟

poj2796 维护区间栈//单调栈

http://poj.org/problem?id=2796 题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以4为最小值,向左右延伸,6 4 5  值为60....... 思路:解决完为这道题目,我才真正明白了单调栈的原理,它就是以某一个值为最小(最大)值,向这个值的两侧延伸,遇到大于它(小于它)的值,就将它延伸的范围扩大,当然,一般来说,要这样做的算法复杂度为o(n^2),但是借助栈这个玩意,维护其单调增

四则运算使用栈和后缀表达式

我们在一般的四则运算都是中缀表达式. 别问我什么是中缀表达式. 我就知道符号两边是数字.也就是符号在中间. 1+3 什么是后缀表达式呢? 13+ 符号在后面. 那么就有人奇怪了,为什么我要使用后缀表达式呢? 问题就是运算的时候,在编程实现的时候,后缀表达式比中缀表达式好用呗. 没事,不理解那里好用没事,我们先把中缀表达式转换成后缀表达式然后实际看看就知道了. 从左到右依次读取 运算数,输出 左括号,入栈 右括号,将栈顶的运算符并输出,直到遇到左括号 运算符 { 若优先级大于栈顶运算符,入栈 若优

栈的应用 - 后缀表达式转中缀表达式

有关栈API详情请参看我的另一篇博文:栈的链式存储 - API实现 实例: 5 + 4=> 5 4 + 1 + 2 * 3 => 1 2 3 * + 8 + ( 3 – 1 ) * 5 => 8 3 1 – 5 * + 中缀表达式符合人类的阅读和思维习惯 后缀表达式符合计算机的"运算习惯" 中缀转后缀算法: 遍历中缀表达式中的数字和符号 对于数字:直接输出 对于符号: 左括号:进栈 运算符号:与栈顶符号进行优先级比较 若栈顶符号优先级低:此符合进栈 (默认栈顶若是左括