您的位置:首页 > 理论基础 > 数据结构算法

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

2017-04-26 23:28 453 查看
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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 顺序表