----by core 第四组 ( 邹卫其 范力 )
一. 项目介绍
1.
2. 将四则运算的计算功能包装在一个模块中( class 或 DLL)
3. 将 core 模块通过一定的 API 接口 (Application Programming Interface) 来和 UI 组对接
三. 代码实现
1. 定义 Core 类(封装成大类)
1 class Core 2 { 3 private: 4 int que_num = 100; //题目数量 5 int data_num = 10; //操作数数量 6 int range = 5; //计算的数值范围 7 int opr_type = 3; //操作符种类 0.加减 1.加减乘 2.加减乘除 3.加减乘除乘方 8 int data_type = 1; //0整数 1小数 2分数 9 int accuracy = 2; 10 string* que = new string[que_num + 1]; 11 string* ans = new string[que_num + 1]; 12 public: 13 void set_que_num(int a) { que_num = a; } 14 void set_data_num(int a) { data_num = a; } 15 void set_range(int a) { range = a; } 16 void set_opr_type(int a) { opr_type = a; } 17 void set_data_type(int a) { data_type = a; } 18 void set_accuracy(int a) { accuracy = a; } 19 int get_que_num() { return que_num; } 20 int get_data_num() { return data_num; } 21 int get_range() { return range; } 22 int get_opr_type() { return opr_type; } 23 int get_data_type() { return data_type; } 24 int get_accuracy() { return accuracy; } 25 string *getQue(); 26 string *getAns(); 27 private: 28 string expstring(Node *root); 29 Node *creatOptree(); 30 Node calc(Node *root); 31 void previsite(Node *head); 32 char operat(); 33 char int_operat(); 34 int get_factor(int a); 35 };
2. 设置类的参数并调用示例
1 int main() 2 { 3 Core cal; 4 string *q, *a; 5 6 cal.set_data_num(10); 7 cal.set_que_num(100); 8 cal.set_range(10); 9 cal.set_opr_type(3); 10 cal.set_data_type(1); 11 cal.set_accuracy(3); 12 13 q = cal.getQue(); 14 a = cal.getAns(); 15 for (int i = 1; i <= cal.get_que_num(); i++) 16 { 17 cout << q[i] << " = " << a[i] << endl << endl; 18 } 19 20 system("pause"); 21 return 0; 22 }
3. 定义节点 Node 类
1 class Node 2 { 3 public: 4 Node() { top = -1; bottom = -1; operat = 0; left = NULL; right = NULL; } 5 Node(int t, int b, char opr) { top = t; bottom = b; operat = opr; left = NULL; right = NULL; } 6 void simp(); 7 int gcd(int p, int q); 8 Node operator + (Node n2); 9 Node operator - (Node n2); 10 Node operator * (Node n2); 11 Node operator / (Node n2); 12 Node operator ^ (Node n2); 13 Node operator = (Node n2); 14 15 public: 16 int top; 17 int bottom; 18 char operat; 19 class Node *left; 20 class Node *right; 21 22 }; 23 24 Node Node::operator + (Node n2) 25 { 26 Node n; 27 n.top = top*n2.bottom + bottom*n2.top; 28 n.bottom = bottom*n2.bottom; 29 n.operat = 0; 30 n.left = NULL; 31 n.right = NULL; 32 n.simp(); 33 return n; 34 } 35 Node Node::operator - (Node n2) 36 { 37 Node n; 38 n.top = top*n2.bottom - bottom*n2.top; 39 n.bottom = bottom*n2.bottom; 40 n.operat = 0; 41 n.left = NULL; 42 n.right = NULL; 43 n.simp(); 44 return n; 45 } 46 Node Node::operator * (Node n2) 47 { 48 Node n; 49 n.top = top*n2.top; 50 n.bottom = bottom*n2.bottom; 51 n.operat = 0; 52 n.left = NULL; 53 n.right = NULL; 54 n.simp(); 55 return n; 56 } 57 Node Node::operator / (Node n2) 58 { 59 Node n; 60 n.top = top*n2.bottom; 61 n.bottom = bottom*n2.top; 62 n.operat = 0; 63 n.left = NULL; 64 n.right = NULL; 65 n.simp(); 66 return n; 67 } 68 Node Node::operator ^ (Node n2) 69 { 70 Node n; 71 n.top = (int)pow(top, n2.top); 72 n.bottom = (int)pow(bottom, n2.top); 73 n.operat = 0; 74 n.left = NULL; 75 n.right = NULL; 76 n.simp(); 77 78 return n; 79 } 80 Node Node::operator = (Node n2) 81 { 82 top = n2.top; 83 bottom = n2.bottom; 84 operat = n2.operat; 85 return Node(n2.top, n2.bottom, 0); 86 }
4. 随机生成一颗算数表达式树
1 Node* Core::creatOptree() 2 { 3 Node *head = NULL, *p = NULL, *q = NULL; 4 int i = 0, j = 0; 5 head = new Node; 6 head->operat = '+'; 7 8 for (i = 1, j = 0; i < data_num - 1; i++) 9 { 10 p = head; 11 while (p) 12 { 13 if (rand() % 2) { 14 if (p->left) p = p->left; 15 else { 16 q = new Node; 17 if (data_type == 0) q->operat = int_operat(); 18 else q->operat = operat(); 19 p->left = q; 20 break; 21 } 22 } 23 else { 24 if (p->right) p = p->right; 25 else { 26 q = new Node; 27 if (data_type == 0) q->operat = int_operat(); 28 else q->operat = operat(); 29 p->right = q; 30 break; 31 } 32 } 33 }//end while 34 }//end if 35 return head; 36 } 37 38 void Core::previsite(Node *head) 39 { 40 if (!head) return; 41 class Node *q = NULL, *p = NULL; 42 if (head->operat && opr_type == 3 && !head->left && !head->right) 43 { 44 int temp = 0; 45 temp = rand() % 4; 46 if (temp == 0) head->operat = '^'; 47 } 48 49 if (head->operat && data_type == 0 && (opr_type == 2 || opr_type == 3) && !head->left && !head->right) 50 { 51 int temp = 0; 52 temp = rand() % 4; 53 if (temp == 0) head->operat = '/'; 54 } 55 56 if (head->operat && !head->left) 57 { 58 p = new Node; 59 //reset(q); 60 p->bottom = rand() % range + 1; 61 p->top = rand() % range + 1; 62 if (data_type == 0) p->bottom = 1; //整数 63 if (data_type == 0 && head->operat == '/') p->top = rand() % range + 1; 64 if (data_type == 1) //小数 65 { 66 p->bottom = 20; 67 p->top = rand() % (20 * range); 68 } 69 if (head->operat == '^') 70 { 71 int min = (range < 6) ? range : 6; 72 p->bottom = 1; 73 p->top = rand() % min + 1; 74 } 75 head->left = p; 76 } 77 if (head->operat && !head->right) 78 { 79 q = new Node; 80 //reset(q); 81 q->bottom = rand() % range + 1; 82 q->top = rand() % range + 1; 83 if (data_type == 0) q->bottom = 1; //整数 84 if (data_type == 0 && head->operat == '/') q->top = get_factor(head->left->top); 85 if (data_type == 1) //小数 86 { 87 q->bottom = 20; 88 q->top = rand() % (20 * range); 89 } 90 if (head->operat == '^') //乘方 91 { 92 int min = (range <= 5) ? range : 5; 93 q->bottom = 1; 94 q->top = rand() % min + 1; 95 } 96 head->right = q; 97 } 98 previsite(head->left); 99 previsite(head->right); 100 101 }
5. 计算表达式树数值
1 Node Core:: calc(Node *root) //计算树的值 2 { 3 Node answer; 4 if (root == NULL) 5 return answer; 6 char opr = root->operat; 7 8 if (opr == 0) 9 { 10 return *root; 11 } 12 else if (opr == '+') 13 { 14 return calc(root->left) + calc(root->right); 15 } 16 else if (opr == '-') 17 { 18 answer = (calc(root->left) - calc(root->right)); 19 if (answer.top < 0) 20 { 21 Node *temp = root->left; 22 root->left = root->right; 23 root->right = temp; 24 answer.top *= -1; 25 } 26 return answer; 27 } 28 else if (opr == '*') 29 { 30 return calc(root->left) * calc(root->right); 31 } 32 33 else if (opr == '/') 34 { 35 if (data_type == 0) 36 { 37 38 } 39 return calc(root->left) / calc(root->right); 40 } 41 42 else if (opr == '^') 43 { 44 return calc(root->left) ^ calc(root->right); 45 } 46 else 47 return answer; 48 }
6. 打印中缀表达式
1 string Core::expstring(Node *root) //生成中缀表达式 分子分母间用 | 2 { 3 if (root == NULL) 4 return que[0]; 5 if (root->left) 6 { 7 if ((root->left->operat == '+' || root->left->operat == '-') && (root->operat == '*' || root->operat == '/')) 8 { 9 que[0] += "( "; 10 expstring(root->left); 11 que[0] += ") "; 12 } 13 else if (root->operat == '^' && root->left->operat) 14 { 15 que[0] += "( "; 16 expstring(root->left); 17 que[0] += ") "; 18 } 19 else 20 expstring(root->left); 21 } 22 23 if (root->operat == 0) 24 { 25 if (data_type == 1) 26 { 27 double t = 1.0 * root->top / root->bottom; 28 stringstream s1; 29 s1 << t; 30 que[0] += s1.str(); 31 que[0] += " "; 32 } 33 else 34 { 35 stringstream s2; 36 s2 << root->top; 37 que[0] += s2.str(); 38 if (root->bottom > 1) 39 { 40 que[0] += "|"; 41 stringstream s3; 42 s3 << root->bottom; 43 que[0] += s3.str(); 44 } 45 que[0] += " "; 46 } 47 } 48 else 49 { 50 que[0] += root->operat; 51 que[0] += " "; 52 } 53 54 if (root->right) 55 { 56 if ((root->operat == '-' || root->operat == '*') && (root->right->operat == '-' || root->right->operat == '+')) 57 { 58 que[0] += "( "; 59 expstring(root->right); 60 que[0] += ") "; 61 } 62 else if (root->operat == '/' && (root->right->operat && root->right->operat != '^')) 63 { 64 que[0] += "( "; 65 expstring(root->right); 66 que[0] += ") "; 67 } 68 else if (root->operat == '^'&& root->right->operat) 69 { 70 que[0] += "( "; 71 expstring(root->right); 72 que[0] += ") "; 73 } 74 else 75 expstring(root->right); 76 } 77 return que[0]; 78 }
7. 生成题目 string 数组
1 string* Core::getQue() 2 { 3 Node *head, result; 4 que = new string[que_num + 1]; 5 ans = new string[que_num + 1]; 6 for (int i = 1; i <= que_num; i++) 7 { 8 head = creatOptree(); 9 previsite(head); 10 result = calc(head); 11 result.simp(); 12 if (result.bottom == 0 || result.top < 0) 13 i--; 14 else 15 { 16 que[0] = ""; 17 que[i] = expstring(head); 18 if (data_type == 1) 19 { 20 double t = 1.0 * result.top / result.bottom; 21 stringstream s1; 22 s1 << t; 23 ans[i] += s1.str(); 24 } 25 else 26 { 27 stringstream s2; 28 s2 << result.top; 29 ans[i] += s2.str(); 30 if (result.bottom > 1) 31 { 32 ans[i] += "|"; 33 stringstream s3; 34 s3 << result.bottom; 35 ans[i] += s3.str(); 36 } 37 } 38 } 39 } 40 return que; 41 }
8. 生成答案 string 数组
1 string* Core::getAns() 2 { 3 if (data_type == 1) 4 { 5 for (int i = 1; i <= que_num; i++) 6 { 7 for (int j = 0; ans[i][j]; j++) 8 if (ans[i][j] == '.') 9 { 10 for (size_t k = j + accuracy + 1; k < ans[i].length(); k++) 11 ans[i][k] = '