数据结构之栈

/*
 * Copyright (c) 2012 Fang Ying (Y. Fang), NEU Electric Engineering 20092725 ,fangying7@gmail.com
 * Copyright (c) GPLv3
 * All Rights Reserved.
 * This program is free software; 
 *you can redistribute it and/or modify it under the terms of the GNU General Public License V3 as published by the
 * Free Software Foundation, either version 2 or any later version.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details. A copy of the GNU General Public License is available at:
 * http://www.fsf.org/licensing/licenses
 */
 
#ifndef _SQ_STACK_H_
#define _SQ_STACK_H_

#include <iostream>

using namespace std;

template <class T>                //模板声明
class sq_stack
{
private:
        int max;                //存储空间容量
        int top;                //栈顶指针
        T *s;                    //顺序栈的存储空间首地址
public:
        sq_stack(int max);        //构造函数,建立空栈
        ~sq_stack();            //析构函数
        void print();            //顺序输出栈顶指针和栈中的元素
        int  flag();            //检测顺序栈的状态
        void push(T);            //压栈
        T      pop();                //弹栈
        T      read();            //读取栈顶数据
};

//建立容量为max的空栈
template <class T>
sq_stack<T>::sq_stack(int  max)
{
    this->max = max;            //存储空间
    s = new T[max];                //申请内存空间
    top = 0;
    return;
}

//顺序输出栈顶指针与栈中的元素
template <class T>
void sq_stack<T>::print()
{
    int i;
    cout<<"top = "<<top<<endl;
    for (i = top ;i > 0 ;i--)
        cout<<s[i-1]<<endl;
    return;
}

//检测顺序栈的状态
template <class T>
int sq_stack<T>::flag()
{
    if (top == max)    return(-1);        //存储空间已满,返回-1
    if (top == 0)    return(0);        //
    return (1);
}

//压栈
template <class T>
void sq_stack<T>::push(T x)
{
    if (top == max)
    {
        cout<<"stack overflow!"<<endl;    
        return;
    }
    top++;                            //栈顶指针进1
    s[top - 1] = x;                    //新元素入栈
    return;
}

//弹栈
template <class T>
T sq_stack<T>::pop()
{
    T y;
    if (top == 0)
    {
        cout<<"underflow!"<<endl; 
        return -1;
    }
    y = s[top-1];
    top -= 1;
    return y;
}

//读取栈顶元素
template <class T>
T sq_stack<T>::read()
{
    if (0 == top)
        {cout<<"Stack empty!"<<endl; return -1;}
    return s[top - 1];            //返回栈顶元素
}

//书序表空间回收
template <class T>
sq_stack<T>::~sq_stack()
{
    delete s;
}
#endif
#include "sq_stack.h"

int main() 
{
    sq_stack<int> st(10);
    st.push(50);
    st.push(60);
    st.push(46);
    st.push(465);
    st.push(712);
    st.push(2747);
    cout<<"输出战中的元素:"<<endl;
    st.print();
    cout<<"栈顶元素:"<<st.read()<<endl;
    cout<<"输出退栈元素:"<<endl;
    cout<<st.pop()<<endl;
    cout<<st.pop()<<endl;
    cout<<st.pop()<<endl;
    cout<<"再次输出栈顶指针和栈中的元素"<<endl;
    st.print();
    return 0;
}

 

#include "sq_stack.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>

using namespace std;

/*======================================================*/
/*               转换当前字符为实数                        */
/*======================================================*/
double char2double(char *s, int *k)
{
    double x,y = 1.0;
    int fla   g = 1;
    char c;
    x = 0.0;
    c = s[*k];                //取得当前符号
    while(c >= '0'&& c<'9' ||c=='.')
    {
        *k = *k + 1;        //扫描指针加一
        if (c >= '0'&& c<='9')
            if(0 == flag)            //转换小数后的值,并将整数部加上
                {y = y*0.1; x=x+(c-48)*y;}
            else
                x=10*x+(c-48);
        else 
            flag = 0;
        c = s[*k];
    }
    return (x);
}
/* ====================================================*/
/*                判断运算符的优先级                       */
/* ====================================================*/
int priority(char op)
{
    int k = 0;
    switch(op)
    {
        case '^':
            k = 3;break;
        case '*':
            k = 2;break;
        case '/':
            k = 2;break;
        case '+':
            k = 1;break;
        case '-':
            k = 1;break;
        case '(':
            k = 0;break;
        case ')':
            k = 0;break;
        case '\0':
            k = -1;break;
        default:
            k = -2;break;
    }
    return (k);        
}

int main() 
{
    sq_stack<double>    sd(50);        //操作数栈
    sq_stack<char>        sp(20);        //操作符栈
    
    char s[60],c;                    //s[60]存放输入的待处理字串
    int flag =1 ,k;
    double x, y;                    //左右操作数

    sp.push('\0');            //表达式结束符进入运算符栈
    cout<<"input formula:"<<endl;
    cin>>s;

    k = 0;                    //扫描指针初始化
    c = s[k];                //取得当前字符
    while(flag)    
    {
        if ((c >= '0')&&( c<='9')||(c == '.'))        //当前字符为数字字符或者小数点
            sd.push(char2double(s ,&k));                //double atof(const char *ptr)将输入的字符串转换为浮点型数据
        else if ((c == '(') || priority(c) > priority(sp.read()))
        //当前符号位"("或者运算符的优先级大于运算符栈的栈顶运算符优先级
        {
            sp.push(c);                    //运算符入栈
            k++;                                    //扫描指针加一
        }
        else if ((c == '\0')&&(sp.read() == '\0'))
            flag = 0;
        else if ((c == ')')&&(sp.read() == '('))
        //当前符号为")",且运算符栈栈顶运算符为"("
        {
            sp.pop();                        //从运算符栈顶退出左括号
            k++;                                    //扫描指针加一
        }
        else if (priority(c) <= priority(sp.read()))
        //当前符号为")",且运算符优先级不大于运算符栈栈顶的优先级
        {
            y = sd.pop();                //从操作数栈取右操作数
            x = sd.pop();                //从操作数栈取左操作数
            c = sp.pop();                //从运算符栈取运算符
            switch(c)
            {
                case '^': x = pow(x,y);break;
                case '*': x = x*y;break;
                case '/': x = x/y;break;
                case '+': x = x+y;break;
                case '-': x = x-y;break;
            }
            sd.push(x);                    //将计算结果放回操作数栈
        }
        c = s[k];                                //取得字符
    }
    cout<<s<<"="<<sd.read()<<endl;        //输出计算结果
    return 0;
}

 

posted @ 2012-06-15 17:52  fangying  阅读(225)  评论(0编辑  收藏  举报