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