數據結構第一次實驗——順序表、棧

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 ;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章