Inputting a Equation in Textfield and Processing it? [actionscript 3.0]

谁说我不能喝 提交于 2020-01-23 19:28:19

问题


I would like to know if theirs a way where you can type in a text field something like "5*5".

And then on enter, the document would take the database and be able to return 25.

I am quite confused due to the fact that content that you input into a textfield must be a String and when you use the Number() converter the system gets confused.


回答1:


You'll need to break your string apart at operators (using regex) and then keep those operators.

I don't have the patience to do this myself but you'll need to prioritise certain operations as well (multiplication before addition, etc).

I've done some code to get you started - note that it only works with really simple algorithms in its current form:

// Finds +, - and *.
var operators:RegExp = /\+|\-|\*/g;
var numbers:RegExp = /\d+/g;


/**
 * Attempts to work with a mathematical formula provided as string.
 * @param str Subject string.
 */
function work(str:String):Number
{
    var ops:Array = str.match(operators);   // List of operators in order.
    var nums:Array = str.match(numbers);    // List of numbers in order.

    var command:Array = [];
    var cmbLen:int = Math.max(ops.length, nums.length);

    for(var i:int = 0; i < cmbLen; i++)
    {
        if(nums[i]) command.push(nums[i]);
        if(ops[i]) command.push(ops[i]);
    }


    // Begin performing the command.
    var val:Number = 0;
    var queuedOperator:String = "";

    for(i = 0; i < command.length; i++)
    {
        // Apply initial value;
        if(i == 0)
            val = Number(command[i]);

        // Work.
        if(i % 2 == 0)
        {
            var num:Number = Number(command[i]);

            // Operate if required.
            if(queuedOperator.length > 0)
            {
                switch(queuedOperator)
                {
                    case "+": val += num; break;
                    case "-": val -= num; break;
                    case "*": val *= num; break;
                }
            }

            queuedOperator = command[i + 1] as String || "";
        }
    }

    return val;
}

And some testing:

trace(work("7 + 10")); // 17
trace(work("5 * 5")); // 25
trace(work("12 - 4")); // 8

trace(work("10 + 5 + 1")); // 16

Feel free to build on this to include more operators (just add them into operators) and sort the command in order of priority. Adding () parenthesis will start to get interesting but with time I'm sure it's possible to get working right.




回答2:


Here's another solution using RegExp. This can calculate whole and decimal numbers using the following signs: ^,%,/,*,+,-. You can also use parantheses e.g. 2^(10/(2+3-2)).

You will need to select the disable keyboard shortcuts option from the control menu when in test movie mode to see the result.

import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;


var tf:TextField = new TextField();
tf.addEventListener(KeyboardEvent.KEY_DOWN,tfKeyDown);
tf.defaultTextFormat = new TextFormat('_sans',24);
tf.autoSize = TextFieldAutoSize.LEFT;
tf.wordWrap = true;
tf.type = TextFieldType.INPUT;
tf.border = true;
tf.x = (stage.stageWidth - 300) * .5;
tf.y = 100;
tf.width = 200;
addChild(tf);
stage.focus = tf;


function tfKeyDown(e:KeyboardEvent):void {
    if (e.keyCode == Keyboard.ENTER) {
        e.preventDefault();
        trace('Input:',tf.text);
        trace('Result:',calculate(tf.text,7));
        trace('-----------------------');
    }
}

function calculate(str:String,maxDecimalCount:int=int.MAX_VALUE):Number {

    var num:String = '-?[0-9]*\\.?[0-9]+';
    var numRX:RegExp = new RegExp(num,'g');
    var rx:RegExp, i:int;

    // normalize minuses and eliminate spaces
    str = str.replace(/--/g,'+').replace(/\s/g,'');

    // calculate parenthesized equations
    while (/\(([^\(\)]+)\)/.test(str)) {
        str = str.replace(/\(([^\(\)]+)\)/g,function() {
            return calculate(String(arguments[1]),int.MAX_VALUE).toString();
        });
    }

    // exponential --> x^y
    rx = new RegExp(num+'(\\^'+num+')+','g');
    str = str.replace(rx,function() {
        var nums = String(arguments[0]).match(numRX);
        var res:Number = Math.pow(Number(nums[0]),Number(nums[1]));
        for (i = 2; i < nums.length; i++) res = Math.pow(res,Number(nums[i]));
        //trace('^ ['+nums+'] =',res);
        return res;
    });
    // modulus --> x%y
    rx = new RegExp(num+'(%'+num+')+','g');
    str = str.replace(rx,function() {
        var nums = String(arguments[0]).match(numRX);
        var res:Number = Number(nums[0]);
        for (i = 1; i < nums.length; i++) res %= Number(nums[i]);
        //trace('% ['+nums+'] =',res);
        return res;
    });
    // divide --> x/y
    rx = new RegExp(num+'(/'+num+')+','g');
    str = str.replace(rx,function() {
        var nums = String(arguments[0]).match(numRX);
        var res:Number = Number(nums[0]);
        for (i = 1; i < nums.length; i++) res /= Number(nums[i]);
        //trace('/ ['+nums+'] =',res);
        return res;
    });
    // multiply --> x*y
    rx = new RegExp(num+'(\\*'+num+')+','g');
    str = str.replace(rx,function() {
        var nums = String(arguments[0]).match(numRX);
        var res:Number = Number(nums[0]);
        for (i = 1; i < nums.length; i++) res *= Number(nums[i]);
        //trace('* ['+nums+'] =',res);
        return res;
    });
    // add or subtract --> x+y or x-y
    rx = new RegExp(num+'([\\+\\-]'+num+')+','g');
    str = str.replace(rx,function() {
        var nums = String(arguments[0]).match(numRX);
        var res:Number = Number(nums[0]);
        for (i = 1; i < nums.length; i++) res += Number(nums[i]);
        //trace('+- ['+nums+'] =',res);
        return res;
    });

    var res:Number = Number(str);
    // if the result is not a number...
    if (isNaN(res)) {
        throw new Error('Please input a valid equation using numbers and the following signs: ()^%/*+-');
    }
    // if the remainder needs to be shortened...
    if (maxDecimalCount < int.MAX_VALUE &&
        int(res) != res && String(res).split('.')[1].length > maxDecimalCount) {
        res = Math.round(res * Math.pow(10,maxDecimalCount)) / Math.pow(10,maxDecimalCount);
    }
    return res; 

}


来源:https://stackoverflow.com/questions/10002850/inputting-a-equation-in-textfield-and-processing-it-actionscript-3-0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!