1.
表達式計算
【問題描述】
求算術表達式的值。算術表達式按中綴給出,以=號結束,包括+,-,*,/四種運算和(、)分隔符。運算數的範圍是非負整數,小於等於109 。
輸入保證語法正確。
【輸入】
一行,包括1個算術表達式。
【輸出】
一行,算術表達式的值
【輸入輸出樣例】
expr.in expr.out
(1+30)/3= 10
【限制】
算術表達式的長度小於等於1000
題目說明
題目名稱 表達式計算
提交文件名 expr
輸入文件名 expr.in
輸出文件名 expr.out
每個測試點時限 1秒
運行內存上限 128M
測試點數目 10
每個測試點分值 10
比較方式 逐字節比較
題目類型 傳統
- 文件輸入輸出;
- 提交源文件即可;所有源文件放到文件夾中,文件夾命名方式:學號+姓名,例53000000高德納;
- 不限定面向對象;
- 可使用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 ;
}