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;
}

0
Exercise/Homework3/Q1.rs Normal file
View File

View 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;
}

View 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
View 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
View 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);
}
}

View 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;
}

View 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;
}