软件工程导论 四则运算

这次作业在基础的四则运算基础上,实现了生成括号的功能。虽然括号生成的规则具有一定的规律性,生成的括号运算式形如$(a \otimes b)$,其中$\otimes$是$+,-,*,/$四种运算符中的一种,但是对于每一对$a$和$b$是否生成括号是随机的,所以依然可以达到练习四则运算的目的。对于$num=3,4,5$个运算符的式子,生成的括号对数的区间是通过自己构造的随机数函数$rnd(2,num)$确定的。

代码

#include "stdafx.h"

#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define DBG(x) cerr << #x << " = " << x << endl;

using namespace std;

int n;
char opt[] = { '.', '+', '-', '*', '/' };

int rnd(int l, int r) { return (rand() % (r - l + 1)) + l; }

/*
int rndEven(int l, int r) {
	int res = rnd(l, r);
	if (res % 2 == 0) return res;
	else {
		if (res - 1 >= l) return res - 1;
		if (res + 1 <= r) return res + 1;
		return -1;
	}
}
*/

int getPriority(char ch) {
	if (ch == '(') return 1;
	else if (ch == '+' || ch == '-') return 2;
	else if (ch == '*' || ch == '/') return 3;
	else return 4;
}

void calculate(stack<double> &mystack, char operation) {
	double num1, num2, num3;
	num2 = mystack.top(); mystack.pop();
	num1 = mystack.top(); mystack.pop();
	if (operation == '+') num3 = num1 + num2;
	if (operation == '-') num3 = num1 - num2;
	if (operation == '*') num3 = num1 * num2;
	if (operation == '/') num3 = num1 / num2;
	mystack.push(num3);
}

double calculator(string str) {
	stack<double> mystack_number;
	stack<char> mystack_operation;
	int i = 0, j, size = str.size();
	char tmp_operation;
	string tmp_num;
	while (i < size) {
		if (str[i] >= '0' && str[i] <= '9') {
			j = i;
			while (j < size && str[j] >= '0' && str[j] <= '9') { j++; }
			tmp_num = str.substr(i, j - i);
			mystack_number.push(atoi(tmp_num.c_str()));
			i = j;
		} else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
			if (mystack_operation.empty()) {
				mystack_operation.push(str[i]);
			} else {
				while (!mystack_operation.empty()) {
					tmp_operation = mystack_operation.top();
					if (getPriority(tmp_operation) >= getPriority(str[i])) {
						calculate(mystack_number, tmp_operation);
						mystack_operation.pop();
					} else break;
				}
				mystack_operation.push(str[i]);
			}
			i++;
		} else {
			if (str[i] == '(') mystack_operation.push(str[i]);
			else {
				while (mystack_operation.top() != '(') {
					tmp_operation = mystack_operation.top();
					calculate(mystack_number, tmp_operation);
					mystack_operation.pop();
				}
				mystack_operation.pop();
			}
			i++;
		}
	}
	while(!mystack_operation.empty()) {
		tmp_operation = mystack_operation.top();
		calculate(mystack_number, tmp_operation);
		mystack_operation.pop();
	}
	return mystack_number.top();
}

string make(int x) {
	string res; stringstream ss;
	ss << x;
	ss >> res;
	return res;
}

string make1() {
	int op = rnd(1, 4), k1, k2;
	if (op == 1 || op == 3) {
		k1 = rnd(1, 100);
		k2 = rnd(1, 100);
	}
	if (op == 2) {
		k1 = rnd(1, 100);
		k2 = rnd(1, 100);
		if (k1 < k2) swap(k1, k2);
	}
	if (op == 4) {
		k1 = rnd(1, 100);
		vector<int> vec;
		for (int i = 1; i * i <= k1; i++) {
			if (k1 % i == 0) {
				vec.push_back(i);
				if (i * i != k1) vec.push_back(k1 / i);
			}
		}
		int sz = vec.size();
		k2 = vec[rnd(0, sz - 1)];
	}
	return make(k1) + opt[op] + make(k2);
}

string make2() {
	return "(" + make1() + ")";
}

int main(int argc, char *argv[]) {
	srand((unsigned)time(NULL));
	FILE *it; freopen_s(&it, "result.txt", "w", stdout);

	cin >> n;
	cout << "2017013465\n";
	while (n--) {
		int num1 = rnd(3, 5);
		string str[15], res = "";
		if (num1 == 3 || num1 == 4) {
            int flag = rnd(1, 100) % 2;
            if(flag) str[1] = make1(), str[2] = make1();
            else str[1] = make2(), str[2] = make2();

            flag = rnd(1, 100) % 2;
            if(flag)res += str[1] + '+' + str[2];
            else res += str[1] + '*' + str[2];
            if(num1 == 4) {
                flag = rnd(1, 100) % 2;
                if(flag)res += '+' + make(rnd(1, 100));
                else res += '*' + make(rnd(1, 100));
            }
		}
        if(num1 == 5) {
            int num2 = rnd(2, 3);
            for(int i = 1; i <= num2; i++) str[i] = make2();
            for(int i = num2 + 1; i <= 3; i++) str[i] = make1();
            int flag = rnd(1, 4);
            if(flag == 1) res += str[1] + '+' + str[2] + '+' + str[3];
            if(flag == 2) res += str[1] + '+' + str[2] + '*' + str[3];
            if(flag == 3) res += str[1] + '*' + str[2] + '+' + str[3];
            if(flag == 4) res += str[1] + '*' + str[2] + '*' + str[3];
        }
		for (int i = 0; i < res.size(); i++) {
			if (res[i] == '/') {
				string s = "÷";
				cout << s;
			} else cout << res[i];
		}
		cout << "=" << calculator(res) << '\n';
	}
	system("pause");
	return 0;
}

  

posted @ 2019-03-26 22:01  WstOne  阅读(187)  评论(0编辑  收藏  举报