In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Editor to share with you how JavaScript to achieve the four calculator functions, I believe that most people do not know much, so share this article for your reference, I hope you will learn a lot after reading this article, let's go to know it!
First, demand + final realization
Note: only the front-end implementation
1. Demand
The source of the demand is that a friend who made embedded CAccord Category + made a remote calculator. The requirement is to support the input of a string of four mixed operation formulas and return the calculated results.
I would like to see if you want to achieve the final effect of such a function with JavaScript encapsulated with Cash Craft + (I will discuss these two implementation ideas after the article, and hope that you can put forward some optimization plans and suggestions.)
two。 Description: the use of string (split, replace) and array (splice) methods.
It mainly uses the method of string cutting into arrays, split, and the method of inserting and deleting in the array, splice. The string regular replace method takes into account that the user's input habits may be different, such as 1, 2, 3, 4 and 3 * 7 + 229.
Support:
Basic four operations 3-6-6-5-6-3
Four decimal operations 3.14 + 6 * 5 / 6-3.5
High order four operations 99 * 94-6.35 + 100 / 1024
Multiple four operations 3 * 3 + 3 * 16-7-5 + 4 / 2 + 22
The above synthesis
Not supported:
Operation with parentheses 1 * (2-3)
Other mathematical operations
3. Code implementation / * * js four mixed operation calculator function (about 20 lines + noodle code) * @ param {string} str input four operation strings * @ return {number} output result * / const calculator = (str) = > {/ / define adding character function const add = (arr, symbol) = > {let length = arr.length While (length > 1) {arr.splice (length- 1,0, symbol); / / add the corresponding operator length--;} return arr after each item / / the purpose is to get an array of varying length} const array = add (str.replace (/\ sroomplagg, "). Split ('+'),'+') .map (it = > add (it.split ('-'),'-') .map (it = > add (it.split ('*'),'*') .map (it = > add (it.split ('/'),'/') .flat (3) / / multiply and divide first ['*','/'] .map (it = > {while (array.includes (it)) {const index = array.findIndex (o = > o = it); index > 0 & & it = ='*'? Array.splice (index-1,3, (Number (Array) * Number (Array)): array.splice (index-1,3, (Number) / Number));}) / / add and subtract, that is, from left to right, calculate while (array.length > 1) {array [1] ='+'? Array.splice (0,3, (Number (array [0]) + Number (Array [2])): array.splice (0,3, (Number (array [0])-Number (Array [2]));} return Number (array [0]) .tofixed (2);}
If you are familiar with ES6 syntax, you should be able to read the code easily. As you must have noticed, this is one of the things that bothers me: should I often write some noodle code in daily development?
II. Implementation steps
(easy-to-understand bosses can skip directly to: step 3)
1. Achieve the most basic addition, subtraction, multiplication and division
two。 Support for high-digit operations
3. Support multiple operations
4. Support...
If you are a beginner, it is recommended to follow the tapping process (or F12 verification + debugging). The programming ability must be based on the amount of code in some way.
1. Version 1: implement basic addition, subtraction, multiplication and division / / version-const calculator = ((str) = > {/ / define the most basic addition, subtraction, multiplication and division const add = (a, b) = > a + b; const sub = (a, b) = > a-b; const mul = (a, b) = > a * b; const div = (a, b) = > a / b; / / process the input string as an array const array = str.split ('') / / * * [handle four basic operations] ['*','/','+','-'] .map (it = > {const index = array.findIndex (o = > o = it); if (index > 0) {switch (it) {case'*': array [index + 1] = mul (Array [index-1], array [index + 1]); break Case'/': array [index + 1] = div (Array [index + 1]); break; case'+': array [index + 1] = add (Number [index + 1]), Number (Array [index + 1]); break Case'-': array [index + 1] = sub (Number, Number); break;} array.splice (index-1, 2)}) / / return array [0]; console.log ('return value:', array [0]);}) ('3'6', 5') / / return value: 5
In this way, a calculator with four mixed operations is realized!
But this calculator is very chicken, only a most basic functional implementation. That is, you can only run a mixed operation of addition, subtraction, multiplication and division of one-digit numbers.
In fact, the idea of the first step is to use the properties of the array to operate four operations at a time by manipulating the array. For the traversal of the array, I give priority to *, / method, followed by +,-method. This is actually problematic, the priority of multiplication and division in the actual operation is not obvious, it can be said that it does not affect the result of the operation (we will discuss it in detail when the implementation of the last version of the article is related to performance). But addition and subtraction will have an impact: it must be implemented from left to right, otherwise it will affect the results of the operation (I won't go into more detail here).
[dealing with four basic operations]
The first step is to process the string as an array const array = str.split (''); this step is illustrated by the code example:
(figure 1)
When dealing with strings, you can see that '3percent, 6percent, 5ax, 6-3' is processed into [' 3percent,'+', '6percent,' *, '5percent,' /', '6percent,' -','3'].
Then in the version-1 code, you can see that the order in which I deal with the operations is ['*','/','+','-'], so version one only supports addition, subtraction, multiplication and division.
Const index = array.findIndex (o = > o = it); this step finds the position in the array where the symbols in step 2 are located (to illustrate, it can also be achieved by using only the string method, that is, finding the position of the string, and then operating, but the array is more commonly used and easier to understand)
When you look at the processed array, the symbol always appears one bit apart, and even the * and / method with higher priority is the result of the operation of the former and the latter where the symbol is located. Array [index + 1] = mul (Array [index-1], array [index + 1]); take the value of the next item where the symbol is located as the result of calling the corresponding operation function
Delete symbol bits with the first item: array.splice (index-1,2)
At this point, you can see that the originally defined array array is changing all the time. Take the print result in the node environment as an example (notice the operation array):
(figure 2)
You can see that each print prints the initial array and the result after it is processed by the splice method.
Disadvantages: this version does not support multiple operations, that is, four mixed operations can only be performed once. At the same time, high-order operations can not be supported.
two。 Version 2: realize the operation of high digits
In figure 1
If it involves a high bit (more than one bit) numeric operation string, simply using the split ('') method will process the two-digit values into two items of the array, that is, affect the operation result.
So I need a method to get the string I want after receiving a string:
(figure 3)
As shown in figure 3, ary is what is needed.
Therefore, the process from str to ary in figure 3 is what this release needs to implement:
/ * to achieve numeric segmentation of strings * @ param {string} strs input string:'12'33 strs 3'9'10'* @ returns array ['12','*','33','/','3','+','9','+' '10'] * / const split = () = > {const result = str.split (' +') / encounter + is processed as an array .map (it = > {return it.split ('-') / encounter-as an array .map (it = > {return it.split ('*') / encounter * as an array .map ( It = > {return it.split ('/') / encounter / process as an array}) return result.flat (3) }
When I designed this algorithm, I didn't have a good idea for a moment. This function treats the string as a multi-dimensional array, and then flattens the array. As shown in figure 4:
(figure 4)
In figure 4, the function is executed to get a multi-dimensional array (in fact, the highest is only a three-dimensional array). The printed result of the return value result shows that the array basically meets the needs: ['31arrays,' +', '62arrays,' *', '5arrays,' /', '6numbers,' -','3'].
Next, put an operator on it:
/ * Definitions add character function * @ param {string []} result passed in array ['31characters,' 62examples 5Accords 6-3'] * @ param {string} symbol passed in operator * @ returns array ['31characters,' +', '62march 5ax 6-3'] * / const add = (result, symbol) = > {let length = result.length While (length! = = 1) {result.splice (length- 1,0, symbol); / / add the corresponding operator length--;} return result; / / after each item in order to get an array of varying length.
For example, if you pass in ['31','62'5 Universe 6-3'], you only need to add'+ 'after the first item.
The purpose of the implementation is to add operators for each item in the array split because of'+', taking into account multiple operations, so the while loop statement is used here and is controlled by a variable length (you can also traverse the array or for loop array to do this)
The test results are shown in figure 5:
(figure 5)
This enables the input of this numeric array of arbitrary length to return a signed array.
[review]:
The overall implementation of the above two functions is to split the array according to symbols and add symbols according to the passed array and symbols:
Combine the two functions and simplify the code (in fact, I personally like to write noodle code, but it may not be good for reading, but it looks more comfortable):
/ / define the add character function const add = (result, symbol) = > {let length = result.length; while (length! = = 1) {result.splice (length- 1,0, symbol); / / add the corresponding operator length--;} return result after each item / / the purpose is to get an array of varying length} const array = (strs = str) = > add (strs.split ('+'),'+') .map (it = > add (it.split ('-'),'-') .map (it = > add (it.split ('*'),'*') .map (it = > add (it.split ('/')) '/'). Flat (3)
That is, the input of any operation string can be processed as the desired array, as shown in figure 6:
(figure 6)
The array function binds the return value of the internal handler directly later.
If there is a better implementation of the above algorithm design, I hope some friends can point out that we can learn from each other.
3. Support multiple operations
Back to version 1, the current implementation only supports four mixed operations at one time, and a more reasonable implementation should be multiplication and division, addition and subtraction, and execution if it appears first.
Complete operation code:
Const calculator = (str) = > {const add = (result, symbol) = > {let length = result.length; while (length > 1) {result.splice (length- 1,0, symbol); length--;} return result } const array = add (str.replace (/\ sbadger g, "). Split ('+'),'+') .map (it = > add (it.split ('-'),'-') .map (it = > add (it.split ('*'),'*') .map (it = > add (it.split ('/'),'/') .flat (3) / / multiply and divide while (array.includes ('*') | | array.includes ('/')) {const itSymbol = array.find (o = > o ='*'| o ='/'); const index = array.findIndex (o = > o ='*'| o ='/'); index > 0 & & itSymbol = ='*'? Array.splice (index-1,3, (Number (Array) * Number (Array)): array.splice (index-1,3, (Number) / Number));} / / perform addition and subtraction, that is, calculation while from left to right (array.length > 1) {array [1] ='+'? Array.splice (0,3, (Number (array [0]) + Number (Array [2])): array.splice (0,3, (Number (array [0])-Number (Array [2]));} return Number (array [0]) .tofixed (2);}
Note: it is important to note that because personal habits are different, so input with spaces, so here before dealing with strings first used a regular expression str.replace (/\ s _ blank _ g, ") (to remove spaces).
Wait, what did I just think of?
If everyone consciously adds a space to separate the operator from the numeric value when typing.
Is it possible to save the string processing in my previous version 2?
Therefore, as a developer, we must pay attention to norms, pay attention to norms!
In the complete code above
It simplifies the call of addition, subtraction, multiplication and division function, and uses array.splice (index-1,3, operation) operation to operate two parameters directly.
After getting the operable array array, multiplication and division are performed first, and then addition and subtraction are performed.
Multiplication and division first determine whether there are * or / two symbols, if so, find the position of the symbol, calculate each multiplication and division, according to mathematical thinking, who is the first to operate who (but I still stipulate to calculate all * first, and then calculate all / this way as the final implementation and put it at the beginning of the article. Because really in the operation, the sequence of multiplication and division does not seem to have much to do with the results, but to me, I feel that multiple execution of includes and find may cause more performance loss in this set of implementations)
When all the multiplication and division are done, only addition and subtraction are left, and then add and subtract sequentially.
Finally, keep two decimal places.
In fact, this code is more in line with mathematical thinking, first multiplication and division (who is the first to operate who), and then addition and subtraction.
If you have any other ideas, you can discuss it together.
Third, think about back-end thinking
1. Implement inverse Polish expression
1-2-3 this is an infix expression, the human brain is easy to calculate, the result is 7. Of course, it is also easy for the computer to process this expression.
When we type 1.2 + (- 1 to 3) * 2, the human brain needs to think about it, but the computer can still calculate the results quickly through fixed code.
However, when we randomly enter the infix expression XXX, the human brain can calculate the results manually, and it is impossible for the computer to express one code block at a time, so how can the computer achieve general and fast calculation? The answer is the suffix expression.
Infix and suffix expressions are involved in the data structure, so I won't talk about the concept. Let's manually simulate the computer's process of calculating string expressions.
two。 Infix expression = > suffix expression
What is easy for a computer to evaluate is a suffix expression, and the whole process is to convert a known infix expression into a suffix expression.
2.1 define [Operand stack] and [operator stack]:
2.2 operator stack off the stack, Operand stack into the stack, the above expression can be: 123 distinct + this is a simple suffix expression.
2.3 when the computer calculates the suffix expression: the operator stack reads *, the Operand stack reads 2 and 3 to get the result 6, and then the operation 1 + 6 = 7.
3. More complex expression evaluation
Enter the stack:
(the latter-enters the Operand stack as a negative number (if used as a symbol bit, the later calculation will be 1.1-30)
As above, except that the operator stack is encountered (enter the operator stack later
Until you meet)
3.1 use the # symbol to distinguish between negative numbers, high digits, and symbolic bits
3.2 so the suffix expression is: #-1.1, 3, 10, 10, 3, 3, 10, 3, 10, 3, 3, 10, 10, 2, 3, 3, 3, 10, 10, 2, 2, 3, 3, 3, 10, 10, 2, 3, 3, 3, 10, 2, 3, 3, 3, 10, 10, 2, 3, 3, 10, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 10, 10, 3, 10, 3, 10, 10, 3, 10, 3, 10, 3, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 3, 10, 3, 10, 3, 10, 3, 10,
Unstack process:
If the calculation does not encounter the symbol bit 1 #, take it out in turn.
Until the symbol bit is encountered, three numbers are taken out-1.1 3 10
After the symbol bit is encountered, the stack is out of the result stack, and the result stack is changed to-1.130.
Based on this calculation:
After the stack is completed, the evaluation of the inverse Polish expression is realized.
Front-end thinking
After I got the requirement of [implementing a calculator that supports four mixed operations], I first thought of the string-to-array, then manipulated the array, and then because of the features of the high-level language, many methods have been encapsulated, so it's relatively easy to implement.
Of course, you can also use the front-end code, with the back-end thinking to achieve is also a choice.
These are all the contents of the article "how to realize the four Computing functions of JavaScript Calculator". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 289
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.