#include <iostream> #include <stack> #include <map> using namespace std; stack<int> num; stack<char> op; map<char, int> Hash; bool is_op(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } bool check1(string s) { for(int i=1; i<s.size()-1;i++) if(is_op(s[i])&&is_op(s[i-1])) return true; return false; } bool check2(string s) { stack<char> stk; for (int i = 0; i < s.size()- 1; i++) { if(s[i] != '(' && s[i] != ')') continue; else if(stk.empty()) stk.push(s[i]); else if(stk.top() == '(' && s[i]== ')') stk.pop(); else stk.push(s[i]); } return stk.empty(); } void cal() { int b = num.top(); num.pop(); int a = num.top(); num.pop(); char c = op.top(); op.pop(); if(c == '+') num.push(a + b); if(c == '-') num.push(a - b); if(c == '*') num.push(a * b); if(c == '/') num.push(a / b); } int main() { string s; getline(cin, s); if(check1(s) || !check2(s)) { cout << "NO" << endl; return 0; } Hash['+'] = Hash['-'] = 1; Hash['*'] = Hash['/'] = 2; for (int i = 0; i < s.size()- 1; i++) { if(s[i] >= '0' && s[i] <= '9') { int j = i, n = 0; while(j < s.size() && s[j] >= '0' && s[j] <= '9') n = n * 10 + (s[j++] - '0'); num.push(n); i = j - 1; } else if(s[i] == '(') { op.push(s[i]); } else if(s[i] == ')') { while(op.top() != '(') cal(); op.pop(); } else { while(op.size() && op.top() != '(' && Hash[op.top()] >= Hash[s[i]]) cal(); if(s[i] == '-' && (!i || s[i-1] == '(')) { int j = i + 1, n = 0; while(j < s.size() && isdigit(s[j])) n = n * 10 + (s[j++]-'0'); num.push(-n); i = j - 1; } else op.push(s[i]); } } while(op.size()) cal(); cout << num.top() << endl; return 0; }
时间: 2024-04-17 09:28:11 浏览: 196
这段代码是一个可以计算包含括号和四则运算的后缀表达式的程序。它使用了两个栈,`num` 用于存储操作数,`op` 用于存储操作符。程序中还定义了一个 `Hash` 映射,用于比较操作符的优先级。
在主函数中首先检查输入的后缀表达式是否满足要求。函数 `check` 检查是否存在连续的两个操作符,函数 `check2` 则检查括号是否匹配。如果不满足这些条件,则输出 "NO" 并结束程序。
接下来程序开始遍历后缀表达式的每个字符。如果遇到数字字符将其转换为对应的整数,并将其压入 `num` 栈中。
如果遇到开括号,则将其压入 `op` 栈中。
如果遇到闭括号,则不断进行计算,直到遇到开括号为止。
如果遇到操作符,则比较其与栈顶操作符的优先级,如果栈顶操作符优先级较高,则进行计算,直到栈顶操作符优先级较低或相等。
最后,将计算结果输出。
请注意,该代码在处理后缀表达式时假设输入的表达式是合法的,并且没有除零错误。如果输入的表达式不符合这些条件,可能会导致异常或错误的结果。
如果您对代码有任何疑问或需要进一步的解释,请随时提问。
相关问题
#include <iostream> #include <string> #include <stack> #include <vector> #include <iomanip> using namespace std; 逐行注释以上代码
这是一段C++的程序代码,使用了几个标准库的头文件。以下是逐行的注释:
```
#include <iostream> // 输入输出流库头文件
#include <string> // 字符串库头文件
#include <stack> // 栈库头文件
#include <vector> // 向量库头文件
#include <iomanip> // 格式控制库头文件
using namespace std; // 命名空间
```
这段程序代码导入了五个标准库的头文件,分别是iostream、string、stack、vector、iomanip,它们分别用于处理输入输出、字符串、栈、向量和格式控制。其中iostream是C++中最常用的输入输出流库,string是用于字符串操作的库,stack是用于栈数据结构的库,vector是用于动态数组的库,iomanip是用于格式化输出的库。
最后一行代码使用了命名空间std,这意味着所有的标准库函数和变量都在std命名空间中。如果不使用using namespace std,则需要在使用标准库函数时加上std::前缀。
在不使用任何STL容器的前提下实现这个代码#include <iostream> #include <memory> #include <stack> #include <fstream> #include <vector> #include <cmath> #include <iomanip> #include <exception> #include <climits> #include <array> #include <cstdint> #include <string> using namespace std; class T { public: virtual bool isOperator() = 0; virtual ~T() {} };
可以使用裸指针和自定义容器实现这段代码。
首先,我们需要定义一个自定义容器来存储T类型的指针。这个容器可以使用动态数组实现,需要自己管理内存。下面是一个简单的实现:
```c++
class MyVector {
public:
MyVector() : size_(0), capacity_(0), data_(nullptr) {}
~MyVector() {
clear();
delete[] data_;
}
void push_back(T* ptr) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
data_[size_++] = ptr;
}
void pop_back() {
if (size_ > 0) {
--size_;
}
}
T* back() const {
return size_ > 0 ? data_[size_ - 1] : nullptr;
}
bool empty() const {
return size_ == 0;
}
void clear() {
for (int i = 0; i < size_; ++i) {
delete data_[i];
}
size_ = 0;
}
private:
void reserve(int new_capacity) {
T** new_data = new T*[new_capacity];
for (int i = 0; i < size_; ++i) {
new_data[i] = data_[i];
}
delete[] data_;
data_ = new_data;
capacity_ = new_capacity;
}
int size_;
int capacity_;
T** data_;
};
```
接下来,我们需要定义一个栈,用来存储T类型的指针。这个栈可以使用动态数组实现,也需要自己管理内存。栈的基本操作包括push、pop、top等,可以按照以下方式实现:
```c++
class MyStack {
public:
MyStack() : size_(0), capacity_(0), data_(nullptr) {}
~MyStack() {
clear();
delete[] data_;
}
void push(T* ptr) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
data_[size_++] = ptr;
}
void pop() {
if (size_ > 0) {
--size_;
}
}
T* top() const {
return size_ > 0 ? data_[size_ - 1] : nullptr;
}
bool empty() const {
return size_ == 0;
}
void clear() {
for (int i = 0; i < size_; ++i) {
delete data_[i];
}
size_ = 0;
}
private:
void reserve(int new_capacity) {
T** new_data = new T*[new_capacity];
for (int i = 0; i < size_; ++i) {
new_data[i] = data_[i];
}
delete[] data_;
data_ = new_data;
capacity_ = new_capacity;
}
int size_;
int capacity_;
T** data_;
};
```
最后,我们可以定义一个派生自T的类,来实现isOperator()函数。这个函数在子类中可以根据实际需求来具体实现。
```c++
class MyT : public T {
public:
bool isOperator() override {
// 实现具体的逻辑
return false;
}
};
```
这样,就可以在不使用STL容器的前提下实现这个代码了。完整代码如下:
```c++
#include <iostream>
using namespace std;
class T {
public:
virtual bool isOperator() = 0;
virtual ~T() {}
};
class MyT : public T {
public:
bool isOperator() override {
// 实现具体的逻辑
return false;
}
};
class MyVector {
public:
MyVector() : size_(0), capacity_(0), data_(nullptr) {}
~MyVector() {
clear();
delete[] data_;
}
void push_back(T* ptr) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
data_[size_++] = ptr;
}
void pop_back() {
if (size_ > 0) {
--size_;
}
}
T* back() const {
return size_ > 0 ? data_[size_ - 1] : nullptr;
}
bool empty() const {
return size_ == 0;
}
void clear() {
for (int i = 0; i < size_; ++i) {
delete data_[i];
}
size_ = 0;
}
private:
void reserve(int new_capacity) {
T** new_data = new T*[new_capacity];
for (int i = 0; i < size_; ++i) {
new_data[i] = data_[i];
}
delete[] data_;
data_ = new_data;
capacity_ = new_capacity;
}
int size_;
int capacity_;
T** data_;
};
class MyStack {
public:
MyStack() : size_(0), capacity_(0), data_(nullptr) {}
~MyStack() {
clear();
delete[] data_;
}
void push(T* ptr) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
data_[size_++] = ptr;
}
void pop() {
if (size_ > 0) {
--size_;
}
}
T* top() const {
return size_ > 0 ? data_[size_ - 1] : nullptr;
}
bool empty() const {
return size_ == 0;
}
void clear() {
for (int i = 0; i < size_; ++i) {
delete data_[i];
}
size_ = 0;
}
private:
void reserve(int new_capacity) {
T** new_data = new T*[new_capacity];
for (int i = 0; i < size_; ++i) {
new_data[i] = data_[i];
}
delete[] data_;
data_ = new_data;
capacity_ = new_capacity;
}
int size_;
int capacity_;
T** data_;
};
int main() {
MyVector vec;
vec.push_back(new MyT());
vec.clear();
MyStack stk;
stk.push(new MyT());
stk.clear();
return 0;
}
```
阅读全文