This commit is contained in:
e2hang
2025-10-24 09:52:24 +08:00
parent 5e189f9bb2
commit 218a2fb56a
8 changed files with 1011 additions and 0 deletions

214
Exercise/Homework3/Q1.cpp Normal file
View File

@@ -0,0 +1,214 @@
#include <iostream>
#include <string>
using namespace std;
//<2F><EFBFBD><EBB7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ȻҲ<C8BB><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ң<EFBFBD>
//<2F><><EFBFBD><EFBFBD>
long long fastpow(long long d, long long u){
//d^u<><75><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>
long long result = 1, base = d, b = u;
while(b > 0){
if(b & 1) result *= base;
base *= base;
b >>= 1;
}
return result;
}
int level(char c){
switch(c){
case '+':
case '-': {
return 1;
break;
}
case '*':
case '/': {
return 2;
break;
}
case '^': {
return 3;
break;
}
default: {
return 0;
break;
}
}
}
int findexp(const string& s, int l, int r) {
int pos = -1;
int min_level = 114514;
int js = 0;
for (int i = r; i >= l; i--) {
if (s[i] == ')') js--;
else if (s[i] == '(') js++;
if (js == 0 && level(s[i])) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ҽ<EFBFBD><D2BD>ϵ<EFBFBD>^<5E><>ʹ<EFBFBD><CAB9><<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><=
if ((s[i] == '^' && level(s[i]) < min_level) ||
(s[i] != '^' && level(s[i]) <= min_level)) {
min_level = level(s[i]);
pos = i;
}
}
}
return pos;
}
long long toNum(const string& s, int l, int r) {
long long tmp = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD>
while (l <= r && s[l] == ' ') l++;
while (l <= r && s[r] == ' ') r--;
if (l > r) return 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҵ<EFBFBD><D2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = l; i <= r; i++) {
if (isdigit(s[i])) {
tmp = tmp * 10 + (s[i] - '0');
} else {
return 0; // <20>Ƿ<EFBFBD><C7B7>ַ<EFBFBD>
}
}
return tmp;
}
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵİ汾
long long toNum(const string& s, int l, int r){
long long tmp = 0;
bool neg = false;
if (s[l] == '-') { neg = true; l++; }
for(int i = l; i <= r; i++){
if(isdigit(s[i])) tmp = tmp * 10 + (s[i] - '0');
}
return neg ? -tmp : tmp;
}
*/
struct Node{
char sign;
long long num;
Node* left;
Node* right;
Node(): sign('?'), num(-1), left(nullptr), right(nullptr) {}
Node(char s): sign(s), num(-1), left(nullptr), right(nullptr) {}
Node(long long n): sign('?'), num(n), left(nullptr), right(nullptr) {}
};
class Expression{
public:
string exp;
Node* root;
long long result;
bool isValid;
Expression(const string& s): exp(s), root(nullptr), result(-1), isValid(true) {}
void inorder(Node* r){
if(!r) return;
inorder(r->left);
if (r->sign == '?') cout << r->num;
else cout << r->sign;
inorder(r->right);
}
Node* build(const string& s, int l, int r){
//[l, r]
//<2F><><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD>
while(l <= r && s[l] == ' ') l++;
while(l <= r && s[r] == ' ') r--;
if(l > r) return nullptr;
//<2F><><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD>
if(s[l] == '(' && s[r] == ')'){
bool hasQuote = true;
int js = 0;
for(int i = l; i <= r; i++){
if(s[i] == '(') js++;
else if(s[i] == ')') js--;
if(js == 0 && i != r){
hasQuote = false;
break;
}
}
if (hasQuote) return build(s, l + 1, r - 1);
}
int pos = findexp(s, l, r);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(pos == -1) {
long long x = toNum(s, l, r);
//cout << "*" << r << endl; <20><>Ϊʲô<CAB2><C3B4><EFBFBD><EFBFBD>0
return new Node(x);
//<2F><><EFBFBD>·<EFBFBD><C2B7>ڵ<EFBFBD>
}
Node* tmp = new Node(s[pos]);
tmp->left = build(s, l, pos - 1);
tmp->right = build(s, pos + 1, r);
return tmp;
}
long long calc(Node* r, bool& isValid){
if(!r) return 0;
//<2F><><EFBFBD><EFBFBD>
if(r->sign == '?') return r->num;
//<2F><><EFBFBD><EFBFBD>
long long left = calc(r->left, isValid);
long long right = calc(r->right, isValid);
if(r->num == -1){
char c = r->sign;
switch(c){
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/': {
if(right == 0) {
isValid = false;
return 0;
}
else return left / right;
}
case '^': {
if(left == 0 && right == 0) { isValid = false; return 0; }
return fastpow(left, right);
break;
}
default: return 0;
}
}
}
void print(){
inorder(root);
}
};
int main(){
/*
string s;
getline(cin, s);
Expression tree(s);
tree.root = tree.build(s, 0, s.length() - 1);
//tree.print();
cout << tree.calc(tree.root, tree.isValid) << endl;
//if(!tree.isValid && result != -1) cout << result <<endl;
//else cout << "Invalid" << endl; */
string s;
while(getline(cin, s)){
Expression tree(s);
tree.root = tree.build(s, 0, s.length()-1);
long long result = tree.calc(tree.root, tree.isValid);
if(tree.isValid) cout << result << endl;
else cout << "INVALID" << endl;
}
return 0;
}