数据结构第一次实验——顺序表、栈

本文介绍了一个中缀表达式的计算方法及线性表的实现细节。针对表达式计算,采用栈来处理运算符优先级并计算表达式的值。对于线性表的实现,提供了基于数组的模板类实现,支持插入、获取、删除等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.
表达式计算
【问题描述】
求算术表达式的值。算术表达式按中缀给出,以=号结束,包括+,-,*,/四种运算和(、)分隔符。运算数的范围是非负整数,小于等于109 。
输入保证语法正确。
【输入】
一行,包括1个算术表达式。
【输出】
一行,算术表达式的值
【输入输出样例】
expr.in expr.out
(1+30)/3= 10

【限制】
算术表达式的长度小于等于1000

题目说明
题目名称 表达式计算
提交文件名 expr
输入文件名 expr.in
输出文件名 expr.out
每个测试点时限 1秒
运行内存上限 128M
测试点数目 10
每个测试点分值 10
比较方式 逐字节比较
题目类型 传统

  1. 文件输入输出;
  2. 提交源文件即可;所有源文件放到文件夹中,文件夹命名方式:学号+姓名,例53000000高德纳;
  3. 不限定面向对象;
  4. 可使用STL;

这是栈应用的典型题目,思路是这样的:扫面表达式,遇到运算符,若比栈顶运算符优先级高,运算符压栈,否则不断取栈顶运算符进行运算,直到栈顶运算符优先级比当前的高,最后把刚刚扫描到的运算符压栈;遇到运算数直接压栈。

这里用到了一些小技巧:对于左括号,当它在栈外出现时,应当直接入栈,任何运算符都不应出栈,所以此时它的优先级应该是最高的;在栈内时,除了遇到右括号,遇到其他任何运算符,它都不应该出栈,所以此时它的优先级应该是最低的。

#include <iostream>
#include <stack>
using namespace std;

long long calculate(long long operator1, long long operator2, char operand)
{
    long long ans;
    switch(operand) {
        case '+' : 
            ans = operator1 + operator2;
            break;
        case '-' :
            ans = operator1 - operator2;
            break;
        case '*' :
            ans = operator1 * operator2;
            break;
        case '/' :
            ans = operator1 / operator2;
            break;
        case '%' :
            ans = operator1 % operator2;
            break; 
    }
    return ans;
}
long long doCalculate(stack<long long> &sNum, stack<char> &sOperator)
{
    long long operator1 = sNum.top(); sNum.pop();
    long long operator2 = sNum.top(); sNum.pop();
    char operand = sOperator.top(); sOperator.pop();
    return calculate(operator2, operator1, operand);
}
bool isNum(char c)
{
    if (c <= '9' && c >= '0') return true;
    else return false;
}
bool isOperand(char c)
{
    if (c == '+' || c == '-' || c == '/' || c == '*' || c == '%' || c == '(' || c == ')' || c == '=') return true;
    else return false;
}
bool isValid(char c)
{
    if (isOperand(c) || isNum(c)) return true;
    else return false;
}
int getWeigh(char c) 
{
    if (c == '(') return 3;
    if (c == '+' || c == '-') return 1;
    if (c == '/' || c == '*' || c == '%') return 2;
}
int getWeigh(stack<char> &sOperator) 
{
    if (sOperator.top() == '(') return 0;
    if (sOperator.top() == '+' || sOperator.top() == '-') return 1;
    if (sOperator.top() == '/' || sOperator.top() == '*' || sOperator.top() == '%') 
        return 2;
}
int main()
{
    freopen("expr.in","r",stdin);
    freopen("expr.out","w",stdout);
    char c;
    long long num = 0;
    int isLastNum = 0;
    stack<long long> sNum;
    stack<char> sOperand;
    while (~scanf("%c",&c)) {
//      cout << c ;
        if (isNum(c)) {
            num = num * 10 + (c - '0');
            isLastNum = 1;
        }
        if (isOperand(c)) {
            if (isLastNum) {
                sNum.push(num);
                num = 0;
            } 
            isLastNum = 0;
            if (c == '=') {
//              while (!sOperand.empty()) {
//                  cout << sOperand.top();
//                  sOperand.pop();
//              } 
//              cout << endl;
//              while (!sNum.empty()) {
//                  cout << sNum.top() << " ";
//                  sNum.pop();
//              }
                while (!sOperand.empty()) {
                    sNum.push(doCalculate(sNum, sOperand));
                }
                break;
            } else if (c == ')') {
                while (!sOperand.empty() && sOperand.top() != '(') {
                    sNum.push(doCalculate(sNum, sOperand));
                }
                sOperand.pop();
            } else {
                int weighNow = getWeigh(c);
                while (!sOperand.empty() && weighNow <= getWeigh(sOperand)) {
                    sNum.push(doCalculate(sNum, sOperand));
                }
                sOperand.push(c);
            }
        }
    }
    printf("%lld\n",sNum.top());
    fclose(stdin);
    fclose(stdout);
    return 0;
}

2.
实现线性表
1)创建可容纳M个结点的顺序表,(M>=10);
2)在顺序表中第k个结点后插入一个新结点;
3)存取顺序表中第k个结点的值;
4)删除顺序表中第k个结点;
5)顺序查找值为x的元素在顺序表中的位置(下标)。

这个直接用数组实现就可以了。

#pragma once
#include <cstdlib>
#include <iostream>
using namespace std;
template <class T>
class Seqlist {
    public:
        Seqlist(int num);
        ~Seqlist();
        Seqlist(const Seqlist<T>& sl);
        Seqlist& operator= (const Seqlist<T>& rhs);

        bool isEmpty(void);
        bool isFull(void);

        void insert(int k, const T& item); // index is k - 1
        const T& get(int k);    // index is k - 1
        void del(int k);        // index is k - 1
        int getLoc(const T& item); // just return the index
        void print(void);
    private:
        int maxNum_;
        int curCnt_;
        T* arr_;
        bool isValidIndex(int k); 
};

template <class T>
Seqlist<T>::Seqlist(int num) : maxNum_(num), curCnt_(0)
{
    if (num <= 0) exit(0);
    arr_ = new T[num];
}
template <class T>
Seqlist<T>::Seqlist(const Seqlist<T>& sl) 
{
    maxNum_ = sl.maxNum_;
    curCnt_ = sl.curCnt_;
    arr_ = new T[maxNum_];
    for (int i = 0; i < curCnt_; i ++) {
        arr_[i] = sl.arr_[i];
    }
}
template <class T>
Seqlist<T>::~Seqlist()
{
    delete []arr_;
}
template <class T>
Seqlist<T>& Seqlist<T>::operator= (const Seqlist<T>& rhs)
{
    if (*this != &rhs) {
        delete []arr_;
        maxNum_ = rhs.maxNum_;
        curCnt_ = rhs.curCnt_;
        arr_ = new T[maxNum_];
        for (int i = 0; i < curCnt_; i ++) {
            arr_[i] = rhs.arr_[i];
        }
    }
    return *this;
}
template <class T>
inline bool Seqlist<T>::isEmpty(void) 
{
    return curCnt_ == 0;
}
template <class T>
inline bool Seqlist<T>::isFull(void)
{
    return curCnt_ == maxNum_;
}
template <class T>
inline bool Seqlist<T>::isValidIndex(int k)
{
    return (k >= 0 && k < curCnt_);
}
template <class T>
void Seqlist<T>::insert(int k, const T& item)
{
    if ( isFull()) {
        cout << "FULL ! CANNOT INSERT ANY MORE !" << endl;
        return ;
    }
    if (!isValidIndex(k - 1) && k != 0) {
        cout << "NO SUCH AN INDEX !" << endl;
        return ;
    }
    for (int i = curCnt_; i >= k; i --) {
        arr_[i + 1] = arr_[i];
    }
    curCnt_ ++;
    arr_[k] = item;
    return ;
}
template <class T>
inline const T& Seqlist<T>::get(int k)
{
    if (isValidIndex(k - 1)) {
        return arr_[k - 1];
    } else {
        cout << "NO SUCH AN INDEX !" << endl;
        exit(0);
    }
}
template <class T>
void Seqlist<T>::del(int k)
{
    if (!isValidIndex(k - 1)) {
        cout << "NO SUCH AN INDEX !" << endl;
        exit(0);
    } else {
        for (int i = k; i < curCnt_; i ++) {
            arr_[i - 1] = arr_[i];
        }
        curCnt_ --;
    }
}
template <class T>
int Seqlist<T>::getLoc(const T& item)
{
    int loc = -1;
    for (int i = 0; i < curCnt_; i ++) {
        if (arr_[i] == item) {
            loc = i;
            break;
        }
    }
    return loc;
}
template <class T>
void Seqlist<T>::print(void)
{
    if (isEmpty()) {
        cout << "EMPTY" << endl;
    } else {
        cout << arr_[0];
        for (int i = 1; i < curCnt_; i ++) {
            cout << "->" << arr_[i];
        }
        cout << endl;
    }
    return ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值