我试图在Angular.js中实现一个简单的Revrse Polish Notation计算器,到目前为止代码可以处理像
这样的单位数计算2 3 +
如何修改它以处理多个数字的输入,例如:
122 233 +
在参与此discussion之后,我想到了这个想法。我怀疑我可能必须使用 onkeypress 和 parseInt 和/或 parseFloat ,但我不确定。我期待着你的想法。谢谢。
JavaScript的:
var calcApp = angular.module('calcApp', []);
calcApp.controller('calcCtrl', function ($scope) {
$scope.leftOperand = "";
$scope.operator = "";
$scope.rightOperand = "";
$scope.answer = "";
$scope.setOperand = function (operandEntered) {
($scope.leftOperand)
? $scope.rightOperand += operandEntered + " "
: $scope.leftOperand += operandEntered + " ";
console.log($scope.leftOperand,$scope.rightOperand);
};
$scope.setOperator = function (operatorEntered) {
$scope.operator = operatorEntered;
};
$scope.getAnswer = function () {
var result = $scope.leftOperand + $scope.operator + $scope.rightOperand;
var answer = eval(result);
if (answer % 1 !== 0){ // % 1 to identify floats
$scope.answer = answer.toFixed(2);
}
else {$scope.answer = answer;}
$scope.leftOperand = $scope.answer;
$scope.operator = "";
$scope.rightOperand = "";
};
$scope.setClear = function (a) {
$scope.leftOperand = "";
$scope.operator = "";
$scope.rightOperand = "";
$scope.answer = "";
};
});
答案 0 :(得分:3)
您的第二个示例已经偏离了(A B Operator)
语法。如果您计划保持一致性以使解析更容易,那么应该
122 (233 41234 +) +
与任何编程语言一样,您需要开始做一些额外的解析工作,以解决您不能再简单地拆分空间的事实。如果你这样做了,你最终会用
['122', '(233', '41234', '+)', '+']
解释如何解析自己的特定于域的语言(DSL)超出了本答案的范围。我只想说你可能想要使用标记器来简化工作。
最后,可以使用递归来处理这种类型的嵌套语法。这意味着您将获取已解析的值并在“树”中搜索分支。如果您找到分支,请按照它,如果它有分支,请遵循该分支等。继续跟随分支,直到找到最深的节点。计算它们,然后将它们的值返回一个级别。继续以递归方式执行此操作,最终您将返回到最顶层,并从所有这些子计算中留下一个值。这是您返回给用户的值。
就何时应该执行此操作而言,您可以在每次用户单击按钮时执行此操作,或者仅在他们单击计算器上的“计算”按钮时执行此操作。这取决于你。
答案 1 :(得分:0)
这比我预期的要容易得多,并且不需要onkeypress,ParseInt或ParseFloat。这是最终起作用的:
var calcApp = angular.module("calcApp", []);
calcApp.controller("calcCtrl", function($scope) {
$scope.leftOperand = "";
$scope.operator = "";
$scope.rightOperand = "";
$scope.answer = "";
var left = false; // flags
var right = false;
$scope.setOperand = function(operandEntered) {
if (left == false && operandEntered >= 0 && operandEntered <= 9) {
$scope.leftOperand += operandEntered;
if (operandEntered == "") {
left = true;
}
} else if (right == false) {
$scope.rightOperand += operandEntered;
}
};
$scope.setOperator = function(operatorEntered) {
if (left == true && $scope.rightOperand) {
$scope.operator = operatorEntered;
right = true;
}
else if($scope.rightOperand=="")
{
left = true; // end of leftOperand input
}
};
$scope.getAnswer = function() {
var result = $scope.leftOperand + $scope.operator + $scope.rightOperand;
var answer = eval(result);
if (answer % 1 !== 0) {
// % 1 to identify floats
$scope.answer = answer.toFixed(2);
} else {
$scope.answer = answer;
}
$scope.leftOperand = $scope.answer;
$scope.operator = "";
$scope.rightOperand = "";
};
$scope.setClear = function() {
$scope.leftOperand = "";
$scope.operator = "";
$scope.rightOperand = "";
$scope.answer = "";
left = false;
right = false;
};
});
#answerScreen {
background-color: lightgray;
border: 3px inset white;
font: 23px Arial, Helvetica;
font-weight: bold;
height: 34px;
padding-left: 3px;
width: 215px;
}
button {
border-radius: 10px;
border-color: pink;
font-weight: bold;
height: 2em;
width: 2em;
}
#rpn {
text-align: center;
}
.calcButtonsrow {
padding: 4px;
}
#calcButtonsBox {
border-style: groove;
}
#clear {
background-color: #FFAAAA;
}
body {
padding-top: 7vh;
}
#space {
background-color: #cff;
text-align: center;
padding: 0;
}
.overflow-hidden {
overflow: hidden;
}
#plusSign,
#multiplySign,
#minusSign,
#divideBySign {
border-radius: 10px;
font-weight: bold;
height: 2em;
width: 2em;
}
#plusSign:hover,
#multiplySign:hover,
#minusSign:hover,
#equalSign:hover,
#divideBySign:hover {
background-color: #ff9;
color: black;
}
#equalSign {
color: #FA6800;
}
#modalCalcButt {
height: 150px !important;
width: 150px !important;
}
#OpenSource {
font-weight: bold;
}
<html lang="en-us" ng-app="calcApp" class="full-height">
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="theCalculator" ng-controller="calcCtrl">
<div class="calcButtonsrow" id="1stLine">
<div id="answerScreen">
<span>{{leftOperand}}</span>
<span>{{rightOperand}}</span>
<span>{{operator}}</span>
<span>{{clear}}</span>
</div>
</div>
<div><span>RPN Calculator - Usage: </span><span id="OpenSource">Number(s) {Sp} Number(s) {operator} {=}</span></div>
<div class="calcButtonsrow" id="2ndLine">
<button class="number" id="7" ng-click="setOperand('7')">7</button>
<button class="number" id="8" ng-click="setOperand('8')">8</button>
<button class="number" id="9" ng-click="setOperand('9')">9</button>
<button id="divideBySign" ng-click="setOperator('/')" class=" operator">/</button>
</div>
<div class="calcButtonsrow" id="3rdLine">
<button class="number" id="4" ng-click="setOperand('4')">4</button>
<button class="number" id="5" ng-click="setOperand('5')">5</button>
<button class="number" id="6" ng-click="setOperand('6')">6</button>
<button id="multiplySign" ng-click="setOperator('*')" class=" operator">*</button>
</div>
<div class="calcButtonsrow" id="4thLine">
<button class="number" id="1" ng-click="setOperand('1')">1</button>
<button class="number" id="2" ng-click="setOperand('2')">2</button>
<button class="number" id="3" ng-click="setOperand('3')">3</button>
<button id="minusSign" ng-click="setOperator('-')" class=" operator">-</button>
</div>
<div class="calcButtonsrow" id="5thLine">
<button id="clear" ng-click="setClear('C')">C</button>
<button class="number" id="0" ng-click="setOperand('0')">0</button>
<button id="equalSign" ng-click="getAnswer('=')" ng-disabled="!leftOperand || !rightOperand || !operator">=</button>
<button id="plusSign" ng-click="setOperator('+')" class="operator">+</button>
<button id="space" ng-click="setOperand('')" class="operator">Sp</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js">
</script>
</body>
</html>
解决方案取决于为操作数设置两个标志。最初他们是假的。在用户敲击具有讽刺意味的空字符串的空格按钮时,左标志被设置为真以指示左操作数的输入结束。右操作数的输入结束由用户单击操作员按钮标记。如果用户单击操作符而不是“Sp”按钮,代码也是宽容的,在这种情况下,左操作数的输入结束通过设置左标志来标记。请注意,如果用户选择了错误的操作符,则代码允许轻松选择不同的操作符。