175 lines
6.6 KiB
TypeScript
175 lines
6.6 KiB
TypeScript
import { deepCopy } from "../../../common/net/CovertUtil";
|
||
|
||
class expTable{//表达式和表达式做符合表述
|
||
pre:expTable|string|number = "";
|
||
next:expTable|string|number = "";
|
||
oper:string = "+";
|
||
constructor(one?:expTable|string|number,two?:expTable|string|number,three?:string){
|
||
this.pre = one||0;
|
||
this.next = two||0;
|
||
this.oper = three||"+";
|
||
}
|
||
|
||
calulate(){
|
||
let preResult = 0;
|
||
let nextResult = 0;
|
||
if(this.pre instanceof expTable)
|
||
preResult = this.pre.calulate()
|
||
else
|
||
preResult = Number(this.pre)
|
||
if(this.next instanceof expTable)
|
||
nextResult = this.next.calulate()
|
||
else
|
||
nextResult = Number(this.next)
|
||
return calcExpressionWithSingleOperator(preResult,nextResult,this.oper)
|
||
}
|
||
changeParam(paramChar:string,param:number|undefined){
|
||
if(param==undefined)return
|
||
if(this.pre instanceof expTable)
|
||
this.pre.changeParam(paramChar,param)
|
||
else if(this.pre==paramChar )
|
||
this.pre = param
|
||
if(this.next instanceof expTable)
|
||
this.next.changeParam(paramChar,param)
|
||
else if(this.next==paramChar )
|
||
this.next = param
|
||
}
|
||
}
|
||
|
||
//字符串表达
|
||
/**计算没有括号的表达式的值(操作符限定为'+'、'-'、'*'、'/') et是字符串中包含的表达式对象*/
|
||
function calcExpressionWithoutQuote(expression:string,et:Array<expTable>):expTable {
|
||
if ((expression.indexOf('(') > -1) || (expression.indexOf(')') > -1)) {
|
||
return calcExpression(expression);
|
||
}
|
||
var operators:string[] = [];
|
||
var nums:any[] = [];
|
||
var lastOperatorIndex = -1;
|
||
for (var i = 0; i < expression.length; i++) {
|
||
var charAtIndex = expression.charAt(i);
|
||
if (isOperatorChar(charAtIndex)) {
|
||
operators[operators.length] = charAtIndex;
|
||
let numStr = expression.substring(lastOperatorIndex + 1, i);
|
||
if (numStr.search(/T</i) == -1 )
|
||
nums[nums.length] = numStr
|
||
else
|
||
{
|
||
let arIdx = Number(numStr.substring(2,3))
|
||
nums[nums.length] = et[arIdx]
|
||
}
|
||
|
||
lastOperatorIndex = i;
|
||
}
|
||
if (i == (expression.length - 1) && lastOperatorIndex < i) {
|
||
let numStr = expression.substring(lastOperatorIndex + 1, expression.length);
|
||
if (numStr.search(/T</i) == -1 )
|
||
nums[nums.length] = numStr
|
||
else
|
||
{
|
||
let arIdx = Number(numStr.substring(2,3))
|
||
nums[nums.length] = et[arIdx]
|
||
}
|
||
}
|
||
}
|
||
let calcResult = new expTable()
|
||
if (operators.length <= 0 || nums.length <= 0) {
|
||
calcResult.pre = expression;
|
||
return calcResult
|
||
}
|
||
|
||
while (operators.indexOf('*') > -1 || operators.indexOf('/') > -1) {
|
||
operators.forEach(function (value, index) {
|
||
if (value == '*' || value == '/') {
|
||
// 拿到操作符位置。
|
||
calcResult = new expTable(nums[index],nums[index+1],value)
|
||
//var tempResult = calcExpressionWithSingleOperator(Number(nums[index]), Number(nums[index + 1]), value);
|
||
operators.splice(index, 1);
|
||
//yjk
|
||
nums[index] = calcResult;
|
||
nums.splice(index+1, 1);
|
||
// nums.splice(index, 2, [tempResult]);
|
||
}
|
||
});
|
||
}
|
||
// 现在只剩下'+'、'-'了
|
||
if (operators.indexOf('+') > -1 || operators.indexOf('-') > -1) {
|
||
for (var index = 0; index < operators.length; index++) {
|
||
var value = operators[index];
|
||
if (value == '+' || value == '-') {
|
||
calcResult = new expTable(nums[index],nums[index+1],value)
|
||
//calcResult = calcExpressionWithSingleOperator(calcResult, Number(nums[index + 1]), value);
|
||
}
|
||
}
|
||
return calcResult;
|
||
} else {
|
||
return calcResult;
|
||
}
|
||
}
|
||
|
||
/**
|
||
|
||
* 计算只有一个操作符的表达式的值(操作符限定为'+'、'-'、'*'、'/')
|
||
|
||
*/
|
||
|
||
function calcExpressionWithSingleOperator(num1:number, num2:number, operator:string) {
|
||
if (operator == '+') return num1 * 1 + num2 * 1;
|
||
if (operator == '-') return num1 * 1 - num2 * 1;
|
||
if (operator == '*') return num1 * num2;
|
||
if (operator == '/') return num1 / num2;
|
||
return NaN;
|
||
}
|
||
|
||
|
||
|
||
/** 计算算术表达式的值 带参数的表达式(m,n,p)*/
|
||
|
||
function calcExpression(expression:string) {
|
||
let calcResult = new expTable()
|
||
var EChangeData = new Array<expTable>()
|
||
expression = expression.replace(/\s/g, '').replace(/÷/g, '/').replace(/x/g, '*').replace(/×/g, '*').replace(/X/g, '*');
|
||
if (getCharCountInString(expression, '(') != getCharCountInString(expression, ')'))
|
||
return calcResult;
|
||
while (expression && (expression.indexOf('(') > -1) && (expression.indexOf(')') > -1)) {
|
||
var firstRightQuoteIndex = expression.indexOf(')');
|
||
var leftQuoteIndex = expression.indexOf('(');
|
||
for (var i = leftQuoteIndex; i < firstRightQuoteIndex; i++) {
|
||
if (expression.charAt(i) == '(') {
|
||
leftQuoteIndex = i;
|
||
}
|
||
}
|
||
var tempExpression = expression.substring(leftQuoteIndex + 1, firstRightQuoteIndex);
|
||
let curCalcResult = calcExpressionWithoutQuote(tempExpression,EChangeData);
|
||
EChangeData.push(curCalcResult)
|
||
expression = expression.substring(0, leftQuoteIndex) + `T<${EChangeData.length-1}>` + expression.substring(firstRightQuoteIndex + 1, expression.length);//"E"特殊表达式
|
||
}
|
||
return calcExpressionWithoutQuote(expression,EChangeData);
|
||
}
|
||
/**获取字符串中某子字符串出现次数 */
|
||
function getCharCountInString(strings:string, chars:string) {
|
||
return (strings.split(chars)).length - 1;
|
||
}
|
||
/**判断字符是否是运算符 */
|
||
function isOperatorChar(aimChar:string) {
|
||
return '+-*/'.indexOf(aimChar) > -1;
|
||
}
|
||
|
||
/*计算表达式,带参数*/
|
||
export default class ComputeExpression {
|
||
_expressModule:expTable = new expTable();//表达式
|
||
constructor(expression:string){
|
||
this._expressModule = calcExpression(expression)
|
||
|
||
}
|
||
getResualtByParam(m?:number,n?:number,p?:number,i?:number)
|
||
{
|
||
let tempExp = deepCopy(this._expressModule) as expTable
|
||
tempExp.changeParam('m',m)
|
||
tempExp.changeParam('n',n)
|
||
tempExp.changeParam('p',p)
|
||
tempExp.changeParam('i',i)
|
||
return tempExp.calulate()
|
||
}
|
||
}
|
||
|
||
|