Hm3
This commit is contained in:
214
Exercise/Homework3/Q1.cpp
Normal file
214
Exercise/Homework3/Q1.cpp
Normal 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;
|
||||||
|
}
|
||||||
0
Exercise/Homework3/Q1.rs
Normal file
0
Exercise/Homework3/Q1.rs
Normal file
191
Exercise/Homework3/Q1双栈做法.cpp
Normal file
191
Exercise/Homework3/Q1双栈做法.cpp
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
#include <bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//---------------------------------------------
|
||||||
|
const long long INF = 1LL << 31; // <20><>ĿҪ<C4BF><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ [-2^31, 2^31)
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>ֵԽ<D6B5><D4BD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>Խ<EFBFBD>ߣ<EFBFBD>
|
||||||
|
int level(char op) {
|
||||||
|
switch (op) {
|
||||||
|
case '+': case '-': return 1; // <20>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
case '*': case '/': return 2; // <20>˳<EFBFBD><CBB3>е<EFBFBD>
|
||||||
|
case '^': return 3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
default: return 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ҽ<EFBFBD><D2BD>ϵ<EFBFBD>
|
||||||
|
//---------------------------------------------
|
||||||
|
// ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣨^<5E><><EFBFBD><EFBFBD><EFBFBD>ҽ<EFBFBD><D2BD>ϣ<EFBFBD>a^b^c <20>ȼ<EFBFBD><C8BC><EFBFBD> a^(b^c)
|
||||||
|
bool rightAssoc(char op) {
|
||||||
|
return op == '^';
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣩
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ pow<6F><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>д
|
||||||
|
// ͬʱҪ<CAB1><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<C7B7><F1B3ACB9><EFBFBD>ĿҪ<C4BF><D2AA><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD> int32 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
long long fastpow(long long a, long long b, bool &valid) {
|
||||||
|
long long res = 1;
|
||||||
|
while (b > 0) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>1<EFBFBD><31><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>һ<EFBFBD><D2BB>
|
||||||
|
if (b & 1) {
|
||||||
|
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (a != 0 && llabs(res) > (INF - 1) / llabs(a)) {
|
||||||
|
valid = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
res *= a;
|
||||||
|
}
|
||||||
|
// <><D7BC>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
b >>= 1;
|
||||||
|
if (b) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>һ<EFBFBD><D2BB>ƽ<EFBFBD><C6BD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ
|
||||||
|
if (llabs(a) > (INF - 1) / llabs(a)) {
|
||||||
|
valid = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a *= a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// ִ<><D6B4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>㣺<EFBFBD><E3A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//---------------------------------------------
|
||||||
|
bool apply(stack<long long> &num, stack<char> &op) {
|
||||||
|
if (num.size() < 2 || op.empty()) return false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
long long b = num.top(); num.pop(); // ע<><D7A2>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
long long a = num.top(); num.pop(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
char c = op.top(); op.pop(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
long long res = 0;
|
||||||
|
switch (c) {
|
||||||
|
case '+': res = a + b; break;
|
||||||
|
case '-': res = a - b; break;
|
||||||
|
case '*': res = a * b; break;
|
||||||
|
case '/':
|
||||||
|
if (b == 0) return false; // <20><><EFBFBD>㱨<EFBFBD><E3B1A8>
|
||||||
|
res = a / b; // <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>β
|
||||||
|
break;
|
||||||
|
case '^': {
|
||||||
|
if (b < 0) return false; // <20><>Ŀ<EFBFBD><C4BF>ָ֤<D6A4><D6B8><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool valid = true;
|
||||||
|
res = fastpow(a, b, valid);
|
||||||
|
if (!valid) return false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ
|
||||||
|
if (res >= INF || res < -INF) return false;
|
||||||
|
|
||||||
|
num.push(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>㺯<EFBFBD><E3BAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>б<EFBFBD><D0B1><EFBFBD>ʽ
|
||||||
|
//---------------------------------------------
|
||||||
|
string calcExpr(const string &s) {
|
||||||
|
stack<long long> num; // <20><><EFBFBD><EFBFBD>ջ
|
||||||
|
stack<char> op; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ
|
||||||
|
int n = s.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < n; ) {
|
||||||
|
if (isspace(s[i])) { // <20><><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD>
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD>֧<EFBFBD>ֶ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//-------------------------------------
|
||||||
|
if (isdigit(s[i])) {
|
||||||
|
long long val = 0;
|
||||||
|
while (i < n && isdigit(s[i])) {
|
||||||
|
val = val * 10 + (s[i] - '0');
|
||||||
|
if (val >= INF) return "INVALID"; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
num.push(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//-------------------------------------
|
||||||
|
else if (s[i] == '(') {
|
||||||
|
op.push('(');
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>㵽<EFBFBD><E3B5BD>һ<EFBFBD><D2BB>'('Ϊֹ
|
||||||
|
//-------------------------------------
|
||||||
|
else if (s[i] == ')') {
|
||||||
|
while (!op.empty() && op.top() != '(') {
|
||||||
|
if (!apply(num, op)) return "INVALID";
|
||||||
|
}
|
||||||
|
if (op.empty()) return "INVALID"; // <20><><EFBFBD>Ų<EFBFBD>ƥ<EFBFBD><C6A5>
|
||||||
|
op.pop(); // <20><><EFBFBD><EFBFBD> '('
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//-------------------------------------
|
||||||
|
else {
|
||||||
|
char now = s[i];
|
||||||
|
if (level(now) == 0) return "INVALID"; // <20>Ƿ<EFBFBD><C7B7>ַ<EFBFBD>
|
||||||
|
|
||||||
|
// ջ<><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><DFBB><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD>ҽ<EFBFBD><D2BD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>
|
||||||
|
while (!op.empty() && op.top() != '(' &&
|
||||||
|
(level(op.top()) > level(now) ||
|
||||||
|
(level(op.top()) == level(now) && !rightAssoc(now)))) {
|
||||||
|
if (!apply(num, op)) return "INVALID";
|
||||||
|
}
|
||||||
|
op.push(now);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//-------------------------------------
|
||||||
|
while (!op.empty()) {
|
||||||
|
if (!apply(num, op)) return "INVALID";
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>ֹһ<D6B9><D2BB><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//-------------------------------------
|
||||||
|
if (num.size() != 1) return "INVALID";
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ս<EFBFBD><D5BD><EFBFBD>
|
||||||
|
return to_string(num.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬ÿ<EBA3AC><C3BF>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||||
|
//---------------------------------------------
|
||||||
|
int main() {
|
||||||
|
ios::sync_with_stdio(false);
|
||||||
|
cin.tie(nullptr);
|
||||||
|
|
||||||
|
string s;
|
||||||
|
while (getline(cin, s)) {
|
||||||
|
string ans = calcExpr(s);
|
||||||
|
cout << ans << "\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
194
Exercise/Homework3/Q1过了的版本.cpp
Normal file
194
Exercise/Homework3/Q1过了的版本.cpp
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//<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])) {
|
||||||
|
int lev = level(s[i]);
|
||||||
|
if (lev < min_level || (lev == min_level && s[i] == '^')) {
|
||||||
|
min_level = lev;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return new Node(x);
|
||||||
|
}
|
||||||
|
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 '^': {
|
||||||
|
return fastpow(left, right);
|
||||||
|
}
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void print(){
|
||||||
|
inorder(root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
string s;
|
||||||
|
while(getline(cin, s)){
|
||||||
|
if (s.empty()) {
|
||||||
|
cout << "INVALID" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Expression tree(s);
|
||||||
|
tree.root = tree.build(s, 0, s.length()-1);
|
||||||
|
if (!tree.root) {
|
||||||
|
cout << "INVALID" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
long long result = tree.calc(tree.root, tree.isValid);
|
||||||
|
if(tree.isValid) cout << result << endl;
|
||||||
|
else cout << "INVALID" << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
34
Exercise/Homework3/Q2.rs
Normal file
34
Exercise/Homework3/Q2.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use std::io;
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
let core = "edgnb";
|
||||||
|
let mut s = String::new();
|
||||||
|
io::stdin().read_line(&mut s).unwrap();
|
||||||
|
let mut n: i32 = s.trim().parse().unwrap();
|
||||||
|
|
||||||
|
for i in 0..n{
|
||||||
|
let mut js = 0;
|
||||||
|
let mut cnt = 0;
|
||||||
|
let mut str = String::new();
|
||||||
|
io::stdin().read_line(&mut str).unwrap();
|
||||||
|
let mut num = String::new();
|
||||||
|
io::stdin().read_line(&mut num).unwrap();
|
||||||
|
let mut m: i32 = num.trim().parse().unwrap();
|
||||||
|
|
||||||
|
let mut j = 0;
|
||||||
|
while j <= str.len() - 5{
|
||||||
|
if &str[j..j+5] == core {
|
||||||
|
js += 1;
|
||||||
|
j += 5;
|
||||||
|
if js >= m {
|
||||||
|
cnt += 1;
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
js = 0;
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
79
Exercise/Homework3/Q3.rs
Normal file
79
Exercise/Homework3/Q3.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use std::io::{self, BufRead};
|
||||||
|
|
||||||
|
|
||||||
|
fn next(s: &Vec<char>, start: usize, end: usize) -> Vec<usize> {
|
||||||
|
let n = end - start;
|
||||||
|
let mut nxt = vec![0; n];
|
||||||
|
let mut j = 0;
|
||||||
|
for i in 1..n {
|
||||||
|
while j > 0 && s[start + i] != s[start + j] {
|
||||||
|
j = nxt[j - 1];
|
||||||
|
}
|
||||||
|
if s[start + i] == s[start + j] {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
nxt[i] = j;
|
||||||
|
}
|
||||||
|
nxt
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
let stdin = io::stdin();
|
||||||
|
for line in stdin.lock().lines() {
|
||||||
|
let s = line.unwrap();
|
||||||
|
if s.trim().is_empty() { continue; }
|
||||||
|
|
||||||
|
let c: Vec<char> = s.trim().chars().collect();
|
||||||
|
let n = c.len();
|
||||||
|
let mut nxt = next(&c, 0, c.len());
|
||||||
|
let mut plen = -1;
|
||||||
|
|
||||||
|
//计算P的话可以直接用最长后缀算,使用KMP
|
||||||
|
for len in (1..n).rev() {
|
||||||
|
let mode: Vec<char> = c[n - len..n].to_vec();
|
||||||
|
let tmp: Vec<usize> = next(&mode, 0, mode.len());
|
||||||
|
let mut i = 0;
|
||||||
|
let mut j = 0;
|
||||||
|
while i < n - 1 {
|
||||||
|
while j > 0 && c[i] != mode[j] {
|
||||||
|
j = tmp[j - 1];
|
||||||
|
}
|
||||||
|
if c[i] == mode[j] {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if j == mode.len() {
|
||||||
|
plen = mode.len() as i32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if plen > 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
if plen > 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算Q,用len1和len2,如果2 * qlen > len(s),则len(Q) = 0
|
||||||
|
|
||||||
|
let mut qlen = 0;
|
||||||
|
if nxt[n - 1] > 0 {
|
||||||
|
qlen = nxt[nxt[n - 1] - 1];
|
||||||
|
}
|
||||||
|
if 2 * qlen > n {
|
||||||
|
qlen = 0;
|
||||||
|
} else {
|
||||||
|
qlen = n - 2 * qlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if plen < 0 {
|
||||||
|
plen = 0;
|
||||||
|
}
|
||||||
|
let out = qlen as i32 + plen as i32;
|
||||||
|
println!("{}", out);
|
||||||
|
|
||||||
|
//println!("qlen: {}", qlen);
|
||||||
|
//println!("plen: {}", plen);
|
||||||
|
}
|
||||||
|
}
|
||||||
153
Exercise/Homework3/grok的表达式树模板.cpp
Normal file
153
Exercise/Homework3/grok的表达式树模板.cpp
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
enum class NodeType {
|
||||||
|
OPERAND, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
OPERATOR // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExprNode {
|
||||||
|
public:
|
||||||
|
NodeType node_type;
|
||||||
|
std::unique_ptr<ExprNode> left;
|
||||||
|
std::unique_ptr<ExprNode> right;
|
||||||
|
|
||||||
|
virtual ~ExprNode() = default;
|
||||||
|
virtual std::string toString() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OperandNode : public ExprNode {
|
||||||
|
public:
|
||||||
|
int value;
|
||||||
|
|
||||||
|
OperandNode(int val) : value(val) {
|
||||||
|
node_type = NodeType::OPERAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString() const override {
|
||||||
|
return "Operand(" + std::to_string(value) + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OperatorNode : public ExprNode {
|
||||||
|
public:
|
||||||
|
std::string op;
|
||||||
|
|
||||||
|
OperatorNode(const std::string& oper, std::unique_ptr<ExprNode> l = nullptr, std::unique_ptr<ExprNode> r = nullptr)
|
||||||
|
: op(oper) {
|
||||||
|
node_type = NodeType::OPERATOR;
|
||||||
|
left = std::move(l);
|
||||||
|
right = std::move(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString() const override {
|
||||||
|
std::string left_str = left ? " " + left->toString() : "";
|
||||||
|
std::string right_str = right ? " " + right->toString() : "";
|
||||||
|
return "Operator(" + op + left_str + right_str + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExprTree {
|
||||||
|
private:
|
||||||
|
std::unique_ptr<ExprNode> root;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExprTree(std::unique_ptr<ExprNode> r = nullptr) : root(std::move(r)) {}
|
||||||
|
|
||||||
|
void setRoot(std::unique_ptr<ExprNode> r) {
|
||||||
|
root = std::move(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Inorder Traversal<61><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD>ʽ
|
||||||
|
void inorderTraversal(const std::unique_ptr<ExprNode>& node, std::vector<std::string>& result) const {
|
||||||
|
if (!node) return;
|
||||||
|
inorderTraversal(node->left, result);
|
||||||
|
if (node->node_type == NodeType::OPERAND) {
|
||||||
|
auto operand = static_cast<const OperandNode*>(node.get());
|
||||||
|
result.push_back(std::to_string(operand->value));
|
||||||
|
} else {
|
||||||
|
auto oper = static_cast<const OperatorNode*>(node.get());
|
||||||
|
result.push_back(oper->op);
|
||||||
|
}
|
||||||
|
inorderTraversal(node->right, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toInfixString() const {
|
||||||
|
std::vector<std::string> result;
|
||||||
|
inorderTraversal(root, result);
|
||||||
|
if (result.empty()) return "";
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD>账<EFBFBD><E8B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>ʾ<EFBFBD><CABE><EFBFBD>ȼ<EFBFBD>
|
||||||
|
std::string infix;
|
||||||
|
for (const auto& s : result) {
|
||||||
|
infix += s + " ";
|
||||||
|
}
|
||||||
|
return infix.substr(0, infix.size() - 1); // <20>Ƴ<EFBFBD>ĩβ<C4A9>ո<EFBFBD>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>棬<F2BBAFB0><E6A3AC>֧<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD> + - * / <20><><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>
|
||||||
|
// ע<>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD>ʹ<EFBFBD>õݹ<C3B5><DDB9>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9><EFBFBD><EFBFBD>
|
||||||
|
static std::unique_ptr<ExprNode> buildFromInfix(const std::string& expr, size_t& pos) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD>
|
||||||
|
while (pos < expr.size() && expr[pos] == ' ') ++pos;
|
||||||
|
|
||||||
|
if (pos >= expr.size()) return nullptr;
|
||||||
|
|
||||||
|
char ch = expr[pos];
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
int num = 0;
|
||||||
|
while (pos < expr.size() && isdigit(expr[pos])) {
|
||||||
|
num = num * 10 + (expr[pos++] - '0');
|
||||||
|
}
|
||||||
|
return std::make_unique<OperandNode>(num);
|
||||||
|
} else if (ch == '(') {
|
||||||
|
++pos; // <20><><EFBFBD><EFBFBD> '('
|
||||||
|
auto left = buildFromInfix(expr, pos);
|
||||||
|
auto op_node_raw = buildFromInfix(expr, pos); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
auto right = buildFromInfix(expr, pos);
|
||||||
|
if (pos < expr.size() && expr[pos] == ')') ++pos;
|
||||||
|
if (op_node_raw && op_node_raw->node_type == NodeType::OPERATOR) {
|
||||||
|
auto op_node = std::unique_ptr<OperatorNode>(static_cast<OperatorNode*>(op_node_raw.release()));
|
||||||
|
op_node->left = std::move(left);
|
||||||
|
op_node->right = std::move(right);
|
||||||
|
return std::move(op_node);
|
||||||
|
}
|
||||||
|
return nullptr; // <20><><EFBFBD><EFBFBD>
|
||||||
|
} else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
|
||||||
|
std::string oper(1, expr[pos++]);
|
||||||
|
return std::make_unique<OperatorNode>(oper);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void buildFromInfix(const std::string& expr) {
|
||||||
|
size_t pos = 0;
|
||||||
|
root = buildFromInfix(expr, pos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ʾ<><CABE>ʹ<EFBFBD><CAB9>
|
||||||
|
int main() {
|
||||||
|
// <20>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3 + (4 * 5)
|
||||||
|
auto mul = std::make_unique<OperatorNode>("*");
|
||||||
|
mul->left = std::make_unique<OperandNode>(4);
|
||||||
|
mul->right = std::make_unique<OperandNode>(5);
|
||||||
|
|
||||||
|
auto add = std::make_unique<OperatorNode>("+");
|
||||||
|
add->left = std::make_unique<OperandNode>(3);
|
||||||
|
add->right = std::move(mul);
|
||||||
|
|
||||||
|
ExprTree tree(std::move(add));
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ: " << tree.root->toString() << std::endl;
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: " << tree.toInfixString() << std::endl; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "3 + * 4 5"
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2BBAFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>֣<EFBFBD>
|
||||||
|
ExprTree tree2;
|
||||||
|
tree2.buildFromInfix("3+(4*5)"); // <20><>Ҫ<EFBFBD><D2AA><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: " << (tree2.root ? tree2.root->toString() : "<EFBFBD><EFBFBD>Ч") << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
146
Exercise/Homework3/表达式树模板.cpp
Normal file
146
Exercise/Homework3/表达式树模板.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#include <bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
char sign; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽڵ<D3BD>Ϊ '?'
|
||||||
|
long long num; // <20><><EFBFBD><EFBFBD>
|
||||||
|
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) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
long long fastpow(long long base, long long exp){
|
||||||
|
long long res = 1;
|
||||||
|
while(exp > 0){
|
||||||
|
if(exp & 1) res *= base;
|
||||||
|
base *= base;
|
||||||
|
exp >>= 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||||
|
int level(char c){
|
||||||
|
switch(c){
|
||||||
|
case '+': case '-': return 1;
|
||||||
|
case '*': case '/': return 2;
|
||||||
|
case '^': return 3;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
int findexp(const string &s, int l, int r){
|
||||||
|
int pos = -1;
|
||||||
|
int minLevel = 114514;
|
||||||
|
int balance = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
for(int i = r; i >= l; --i){ // <20>ҽ<EFBFBD><D2BD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ<EFBFBD>
|
||||||
|
if(s[i] == ')') balance++;
|
||||||
|
else if(s[i] == '(') balance--;
|
||||||
|
else if(balance == 0 && level(s[i]) > 0){
|
||||||
|
if(level(s[i]) <= minLevel){
|
||||||
|
minLevel = level(s[i]);
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
||||||
|
long long toNum(const string &s, int l, int r){
|
||||||
|
long long tmp = 0;
|
||||||
|
while(l <= r && isspace((unsigned char)s[l])) l++;
|
||||||
|
while(r >= l && isspace((unsigned char)s[r])) r--;
|
||||||
|
if(l > r) return 0;
|
||||||
|
for(int i = l; i <= r; ++i){
|
||||||
|
if(!isdigit(s[i])) return 0;
|
||||||
|
tmp = tmp * 10 + (s[i] - '0');
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Expression {
|
||||||
|
public:
|
||||||
|
string exp;
|
||||||
|
Node* root;
|
||||||
|
long long result;
|
||||||
|
bool isValid;
|
||||||
|
|
||||||
|
Expression(const string &s): exp(s), root(nullptr), result(0), isValid(true) {}
|
||||||
|
|
||||||
|
Node* build(const string &s, int l, int r){
|
||||||
|
while(l <= r && s[l] == ' ') l++;
|
||||||
|
while(l <= r && s[r] == ' ') r--;
|
||||||
|
if(l > r) return nullptr;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
|
||||||
|
if(s[l] == '(' && s[r] == ')'){
|
||||||
|
int balance = 0;
|
||||||
|
bool hasOuter = true;
|
||||||
|
for(int i = l; i <= r; ++i){
|
||||||
|
if(s[i] == '(') balance++;
|
||||||
|
else if(s[i] == ')') balance--;
|
||||||
|
if(balance == 0 && i < r){
|
||||||
|
hasOuter = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasOuter) return build(s, l+1, r-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = findexp(s, l, r);
|
||||||
|
if(pos == -1){
|
||||||
|
long long val = toNum(s, l, r);
|
||||||
|
return new Node(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 &v){
|
||||||
|
if(!r) return 0;
|
||||||
|
if(r->sign == '?') return r->num;
|
||||||
|
|
||||||
|
long long left = calc(r->left, v);
|
||||||
|
long long right = calc(r->right, v);
|
||||||
|
|
||||||
|
switch(r->sign){
|
||||||
|
case '+': return left + right;
|
||||||
|
case '-': return left - right;
|
||||||
|
case '*': return left * right;
|
||||||
|
case '/':
|
||||||
|
if(right == 0){ v = false; return 0; }
|
||||||
|
return left / right;
|
||||||
|
case '^':
|
||||||
|
if(right < 0){ v = false; return 0; }
|
||||||
|
return fastpow(left, right);
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calc(){
|
||||||
|
isValid = true;
|
||||||
|
result = calc(root, isValid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
string s;
|
||||||
|
while(getline(cin, s)){
|
||||||
|
Expression tree(s);
|
||||||
|
tree.root = tree.build(s, 0, s.length()-1);
|
||||||
|
tree.calc();
|
||||||
|
if(tree.isValid) cout << tree.result << endl;
|
||||||
|
else cout << "INVALID" << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user