Title: Write a program that can automatically generate primary arithmetic

Requirements:

- In addition to integers, support the arithmetic of true fractions
- Allows the program to accept the user to enter the answer, and judge the right and wrong

The algorithm for solving arithmetic has the same problem in the data structure course, but we need to do the result of a given arithmetic topic at that time. According to the inverse Polish expression, the infix conversion to suffix expression is used to solve the stack structure. The difficulty of this task is to randomly generate arithmetic topics. The idea at the beginning is too low to randomly generate a number, an operator, and a number, based on the structure of a regular expression ... But deep down, this method is difficult to implement, because an expression is not only the operand and the +-*/operator, but also the highest-priority operator of parentheses, adding parentheses to a randomly generated operand and a four-operator symbolic stream, to think of the complexity. So the two-fork tree structure is used, the non-endpoint is the operator, the leaf node is the operand, the shape is: a+b,a* (B+c), (A-B) *c/d can be expressed as:

This structure is abstracted as:

It is natural to think of recursive structures, followed by concrete implementation processes.

First define the Expression node class Experssion: The General property is the parent node pointer, parent, the left Dial hand node pointer left, the right child node pointer, and the expression results result, the current operator Oper, Is the left node flag isleft (defined for later addition of parentheses).

In order to support fractional operations, I later defined a value class, where private data is numerator, denominator (int numer,int demon), which allows the integer to be uniformly viewed as a fraction of 1 of the constituent mother. The member functions in the class include, of course, the overloaded functions of the subtraction and comparison operators, but the topic requires that the fractions be shown in the form of the simplest true fractions, so the numerator function gcd is defined. But at the beginning of the implementation, I replaced the data type with the integer type, which is convenient.

Building an expression can be divided into three steps: Creating an expression framework, populating the expression with the resulting frame, and adding parentheses to the expression.

1) Create an expression frame: Void CreateEx (int numofoper)

Where Numofoper is expressed as the number of operators in the expression that is about to be generated, which determines the basic framework of the expression.

The root node of the entire binary tree is a non-endpoint, which represents an operator, and of course the operator is randomly generated. The next step is to assign the number of operators to the left dial hand and right child nodes of the root node.

1 int Numofleftoper = rand ()% numofoper; 2 int Numofrightoper = numofoper-numofleftoper-1; 3 Left->CreateEx (numofleftoper); 4 Right->createex (Numofrightoper);

Recursive generation of left dial hand and right-handed, until the number of operators allocated, the basic framework is formed.

2) Fill expression According to the generated frame: Value fillexframe (int maxnum)

Where maxnum represents the maximum number of operands in an expression that is required by the topic.

The recursive solution is also used.

LResult = Left->fillexframe (maxnum); Rresult = Right->fillexframe (maxnum);

The operand is randomly generated when it is recursively deep into the leaf node. But there are a lot of detail issues to be aware of, the topic requires: The calculation process generated in the problem can not produce negative numbers, that is, the arithmetic expression if there is a e1−e2, such as a sub-expression, then e1≥e2. If there are sub-expressions like e1÷e2 in the generated topic, the result should be a true fraction. This also means that the random generation of operands is also limited. Depending on the operator, LRESULT and Rresult are subject to discussion (where lresult and Rresult represent the left dial hand expression result and the result of the right sub-expression). When Oper is '-', Lresult>=rresult. When Oper is ' ÷ ', Rresult! = 0 && LResult <= rresult. But according to the running program, the leaf node is generated at the bottom, the two leaf nodes can only meet the requirements of the direct parent node operator, in the parent node based on the two leaf nodes and operators calculated results do not necessarily conform to the requirements of the higher node operator, in this case what to do? I stole a little bit of laziness here, and when it happens that Oper is '-', but Lresult < Rresult, this operator becomes the ' ÷ ' number. When Oper is ' ÷ ', Rresult = = 0 or Lresult > Rresult, the oper becomes '-', so you don't have to think about other problems (⊙﹏⊙ B Khan)

Here, the framework is fully populated.

3) Add parentheses to an expression

This is to consider the precedence between the operator and the parentheses, the first definition of the isleft is used at this time, the sub-expression is the current left Dial hand node, the sibling operator does not need parentheses (sibling arithmetic Mr. Foo to the left). When the subexpression is the current right child node, the sibling operator needs parentheses, and that's the difference, and the rest of the case is, of course, the low-priority brackets.

Basically, the expression class is formed, the data type of the operand in the expression becomes the value class already defined, the whole program is basically completed.

Later, I have added this program to the GUI, using MFC, is a simple list control display expression, this control is the last blog in the editable list box. Running results such as:

Personal project: Automatic generation of arithmetic topics summary