括弧つき電卓
♥6 |
Line 221 |
Modified 2009-10-23 12:43:28 |
MIT License
archived:2017-03-07 22:20:45
ActionScript3 source code
/**
* Copyright aomoriringo ( http://wonderfl.net/user/aomoriringo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1wgu
*/
/*
括弧が使用可能な電卓。
文字列自体を処理してるので、キーボードからの入力でもOKです。
デザインは適当。
*/
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style>
Button {
fontSize: 40;
}
TextInput{
fontSize: 20;
}
TextArea{
fontSize: 20;
}
</mx:Style>
<mx:Script>
<![CDATA[
private function input(e:Event):void{
terms.text += e.target.label;
}
private function clear():void{
terms.text = "";
answer.text = "";
}
private function calc():void{
var term:String = terms.text;
var ans:String = termsToNum(term);
answer.text = ans;
}
private function termsToNum(term:String):String{
var formula:String = new String();
var beforeFormula:String = new String();
beforeFormula = removeParent(term);
while(1){
formula = removeParent(beforeFormula);
if(beforeFormula == formula) break;
beforeFormula = formula;
}
trace("formula:"+formula);
return arithmetic(formula);
}
// (------)を外す
private function removeParent(formula:String):String{
// かっこの前後が数字かどうか
// 数字の場合は乗算をしなければならない
var beforeParent:Boolean = false;
var afterParent:Boolean = false;
// これに一文字ずつ入れていく
var tmpChar:String = new String();
var beforeChar:String = new String();
// かっこの中身
var parentheses:String = new String();
// 完成させる文字列(かっこがない)
var tmpFormula:String = new String();
for(var i:int=0 ; i<formula.length ; i++){
tmpChar = formula.charAt(i);
if(tmpChar=="("){
if(!isNaN(Number(beforeChar)) && i!=0){
beforeParent = true;
}
break;
}
tmpFormula += tmpChar;
beforeChar = tmpChar;
}
if(i+1 < formula.length){
var k:int=1;
for(var j:int=i+1 ; j<formula.length ; j++){
tmpChar = formula.charAt(j);
if(tmpChar =="("){
k++;
}
else if(tmpChar ==")"){
k--;
}
if(k==0) break;
}
parentheses = formula.slice(i+1,j);
trace("parent:"+parentheses);
parentheses = termsToNum(parentheses);
if(!isNaN(Number(parentheses))){
if(Number(parentheses)<0){
parentheses = String(-Number(parentheses));
trace("sendReplacePlusMinus"+tmpFormula);
tmpFormula = replacePlusMinus(tmpFormula);
}
}
if(beforeParent==true){
tmpFormula += "*";
}
tmpFormula += parentheses;
if(j+1 < formula.length){
tmpChar = formula.charAt(j+1);
if(!isNaN(Number(tmpChar))){
afterParent = true;
}
if(afterParent == true){
tmpFormula += "*";
}
tmpFormula += formula.slice(j+1,formula.length);
}
}
trace("tmpFormula:"+tmpFormula);
return tmpFormula;
}
// 四則演算
private function arithmetic(formula:String):String{
var tmpChar:String = new String();
//スタック(数)
var numStack:Array = new Array();
//スタック(算術記号)
var calStack:Array = new Array();
var tmpNumber:Array = new Array();
var beforeChar:String = new String();
formula +="=";
for(var i:int=0 ; i<formula.length ; i++){
tmpChar = formula.charAt(i);
//数字
if(!isNaN(Number(tmpChar))){
tmpNumber.push(Number(tmpChar));
}
//小数点
else if(tmpChar=="."){
tmpNumber.push(tmpChar);
}
//数字以外
else{
//演算記号の前の項をスタックに積む
if(tmpNumber.length!=0){
var tmpTerm:String =new String();
for(var j:int=0 ; j<tmpNumber.length ; j++){
tmpTerm += tmpNumber[j];
}
numStack.push(Number(tmpTerm));
tmpNumber = new Array();
}
else if(tmpChar=="-" || tmpChar=="+"){
numStack.push(Number(0));
}
var tmpAns:Number;
// 乗算、除算
switch(beforeChar){
case "*":
term2 = numStack.pop();
term1 = numStack.pop();
tmpAns = term1*term2;
numStack.push(tmpAns);
break;
case "/":
term2 = numStack.pop();
term1 = numStack.pop();
tmpAns = term1/term2;
numStack.push(tmpAns);
break;
default:
calStack.push(beforeChar);
break;
}
beforeChar = tmpChar;
}
}
calStack.reverse();
numStack.reverse();
var tmpCalStack:int = calStack.length;
var tmpCal:String = new String();
// + and -
for(var k:int=0 ; k<tmpCalStack ; k++){
tmpCal = calStack.pop();
var term1:Number = new Number();
var term2:Number = new Number();
switch(tmpCal){
case "+":
term1 = numStack.pop();
term2 = numStack.pop();
tmpAns = term1+term2;
numStack.push(tmpAns);
break;
case "-":
term1 = numStack.pop();
term2 = numStack.pop();
tmpAns = term1-term2;
numStack.push(tmpAns);
break;
}
}
return numStack.pop();
}
//beforeStrの replaceAt番目を replaceCharに書き換える
private function charReplace(beforeStr:String,replaceAt:int,replaceChar:String):String{
var afterStr:String = new String();
afterStr += beforeStr.slice(0,replaceAt);
afterStr += replaceChar;
afterStr += beforeStr.slice(replaceAt+1,beforeStr.length);
return afterStr;
}
private function replacePlusMinus(formula:String):String{
var tmpChar:String = new String();
var afterStr:String = new String();
for(var i:int=formula.length ; i>=0 ; i--){
tmpChar = formula.charAt(i);
if(tmpChar =="+"){
afterStr = charReplace(formula, i, "-");
trace("afterStr:"+afterStr);
return afterStr;
}
else if(tmpChar =="-"){
afterStr = charReplace(formula, i, "+");
trace("afterStr:"+afterStr);
return afterStr;
}
}
return formula;
}
]]>
</mx:Script>
<mx:Panel x="10" y="10" width="424" height="424" layout="absolute">
<mx:TextInput x="10" y="10" width="224" height="74" id="terms" enter="calc()"/>
<mx:Button x="10" y="92" label="+" width="50" height="108" fontSize="30" click="input(event)"/>
<mx:Button x="10" y="208" label="-" width="50" height="50" fontSize="30" click="input(event)"/>
<mx:Button x="10" y="266" label="*" width="50" height="50" fontSize="30" click="input(event)"/>
<mx:Button x="10" y="324" label="/" width="50" height="50" fontSize="30" click="input(event)"/>
<mx:Button x="68" y="92" label="7" width="50" height="50" click="input(event)"/>
<mx:Button x="68" y="150" label="4" width="50" height="50" click="input(event)"/>
<mx:Button x="68" y="208" label="1" width="50" height="50" click="input(event)"/>
<mx:Button x="68" y="266" label="0" width="50" height="50" click="input(event)"/>
<mx:Button x="126" y="92" label="8" width="50" height="50" click="input(event)"/>
<mx:Button x="126" y="150" label="5" width="50" height="50" click="input(event)"/>
<mx:Button x="126" y="208" label="2" width="50" height="50" click="input(event)"/>
<mx:Button x="126" y="266" label="." width="50" height="50" click="input(event)"/>
<mx:Button x="68" y="324" label="(" width="50" height="50" click="input(event)" fontSize="30"/>
<mx:Button x="184" y="92" label="9" width="50" height="50" click="input(event)"/>
<mx:Button x="184" y="150" label="6" width="50" height="50" click="input(event)"/>
<mx:Button x="184" y="208" label="3" width="50" height="50" click="input(event)"/>
<mx:Button x="126" y="324" label=")" width="50" height="50" fontSize="30" click="input(event)"/>
<mx:Button x="184" y="266" label="C" width="50" height="108" click="clear()"/>
<mx:Button x="242" y="92" label="=" width="152" height="282" id="equal" fontSize="500" click="calc()"/>
<mx:TextArea x="242" y="11" width="152" height="73" id="answer" wordWrap="true"/>
</mx:Panel>
</mx:Application>