序言
本篇仅给没有思路的同学们提供参考,请勿用于交作业,或者商业(应该是不可能的)用途,老大哥在看着你.
惯例:阿巴阿巴阿巴阿巴阿巴
项目的准备
首先,你需要一个编译器,那种都可以,初学者我推荐Hbuilder.
然后在编译器中(或许是你的文件夹中)新建一个项目.并且在项目中新建两个文件夹,js与css.通常惯例中,我们把js代码与css分开存放,而不是与index.html放在同一级中.在小型项目中这或许难以理解.有些画蛇添足的味道.
很多习惯都是如此,在当时觉得麻烦不省事,但当你需要构建的是一个大型项目时,这些良好的习惯会帮助你省很多事,
在前端中,html5负责建构静态网页,CSS3负责装饰布局页面,js负责动态页面以及与后端的交互,所以我们完成这个项目的过程也是如此.先写好页面(html以及css),再思考逻辑(js).
最后,再次提醒,如果你进来只是为了COPY代码完成作业的,那你在就业时就会流下悔恨的眼泪
.这是你个人的选择.而愿意学习自我提高的同学,请跟上我的思路.并且在同时思考问题:有没有更好的实现方法?我能不能做得更好更美观?
[1]不光简单还有些难看的前端
下面是h5与C3代码,布局方式使用的是浮动
CSS3{
float: left;
}
页面相当朴素,代码量很少,所以直接使用了内联css
<link rel="stylesheet" type="text/css" href="./css/work.css"/>
<script src="./js/jquery-3.1.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="./js/work.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
*{/* 取消边框 */
margin: 0px;
padding: 0px;
}
body{/* 设置body的外边距 */
padding-left: 30%;
padding-right: 30%;
}
.CountButton{
margin-left:2% ;
margin-bottom: 20px;
float: left;
width: 22%;
height:50px;
border:2px black solid;
}
#Count{
width: 300px;
height: 500px;
padding: 20px;
border:2px black solid;
}
#CountShow{
float: left;
width: 100%;
height:70px;
margin-bottom: 20px;
padding-top: 10px;
border:2px black solid;
}
#Rlist{
float: left;
width: 100%;
height:30px;
margin-bottom: 20px;
border:2px black solid;
}
#ButtonList{
float: left;
width: 100%;
padding-top: 2%;
padding-bottom: 2%;
height:330px;
border:2px black solid;
}
.InputShow{
float: right;
height:30px;
width: 100%;
text-align: right;
}
</style>
</head>
<body>
<div id="Count">
<div id="CountShow">
<font id="Countformula" class="InputShow" size="4" color="" style="margin-bottom: 10px;"></font>
<font id="Addformula" class="InputShow" size="4" color="" ></font>
</div>
<div id="Rlist">
<font id="Result" class="InputShow" size="4" color="" ></font>
</div>
<div id="ButtonList">
<button id="" class="CountButton Count" data-count="+">
<font size="3" color="">加(+)</font>
</button>
<button id="" class="CountButton Count" data-count="-">
<font size="3" color="">减(-)</font>
</button>
<button id="" class="CountButton Count" data-count="*">
<font size="3" color="">乘(*)</font>
</button>
<button id="" class="CountButton Count" data-count="/">
<font size="3" color="">除(/)</font>
</button>
<button id="" class="CountButton Dispose" data-dispose="C">
<font size="3" color="">清除(C)</font>
</button>
<button id="" class="CountButton Dispose" data-dispose="B">
<font size="3" color="">退格(B)</font>
</button>
<button id="" class="CountButton Count" data-count="(">
<font size="3" color="">括号"("</font>
</button>
<button id="" class="CountButton Count" data-count=")">
<font size="3" color="">括号")"</font>
</button>
<button id="" class="CountButton Cnumber" data-event="1">
<font size="4" color="">(一)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="2">
<font size="4" color="">(二)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="3">
<font size="4" color="">(三)</font>
</button>
<button id="" class="CountButton Cnumber" data-event=".">
<font size="3" color="">小数点(.)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="4">
<font size="4" color="">(四)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="5">
<font size="4" color="">(五)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="6">
<font size="4" color="">(六)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="0">
<font size="4" color="">(零)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="7">
<font size="4" color="">(七)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="8">
<font size="4" color="">(八)</font>
</button>
<button id="" class="CountButton Cnumber" data-event="9">
<font size="4" color="">(九)</font>
</button>
<button id="" class="CountButton Dispose" data-dispose="=">
<font size="3" color="">等于(=)</font>
</button>
</div>
</div>
</body>
页面效果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200707171326669.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h1aXNlc2h1YWlrYWk=,size_16,color_FFFFFF,t_70#pic_center)
[2]不难理解还有些弱智的js代码
在贴代码之前,请诸位先思考,你平时是如何计算如10+(10*10+10)/10
这类算式的?是不是先在括号里找乘除法,然后计算括号内的加减法.以此推类.如果不清楚的建议回小学回炉重造,学习算数优先级.
开个玩笑.
基本的逻辑确实如此,以上面的10+(10*10+10)/10
为例
步骤
1: 10+(10*10+10)/10
2: 10+(100+10)/10
3: 10+110/10
4. 10+11
5. 21
我们明白了计算的逻辑,非常的简单,但是使用js代码实现这个逻辑,并输出结果.其中的业务逻辑就有些令人费解了.
在解决简单地二元乘除问题时,我们可以依次获取操作对象,如a,+,b,再使用switch区分处理乘除问题.但在这个问题中我们要考虑计算优先级的问题,不能简单地循环处理.
请思考一下,如果是你的话,你要如何实现?使用何种方法?
用伪代码的方式思考就可以了,并不用具体的步骤,给大家三十秒…
我是十秒钟的分割线
我是十秒钟的分割线
我是十秒钟的分割线
想到的同学可以在评论中写出来,有需要我可以帮助完成代码的实现,现在言归正传.如何实现根据算式的乘除号以及括号,来决定算式的计算顺序?
有些同学会想,诶呀,使用split()将算式以一定方式分开,再依次进行计算不就好了
?
确实,这也是一种解决方式,当但算式为((10+10)*10)+(10/10+10)
这类优先级关系复杂的算式时,这类取巧简单地方式就不适用了.我们需要的是一个能够自动根据计算优先级进行计算的解决方式.
比如,递归调用.
有些同学这时候就要举手提问了.
阿巴阿巴,我知道递归调用可用来解决阶乘问题,但是递归和解决算数优先级之间有什么关系吗?
当然有关系,并且契合度还挺高的.我们先以算式((((10+10)*10)+(10/10+10))
)做个假设:
首先使用递归调用的递推阶段,将算式中的一个个计算单元分解,直至不可再分
1:((10+10)*10)+(10/10+10)
2:((10+10)10)
3:(10+10)
4:10不可再分了
回归
1:处理(10+10)=20,将20传递至上一个函数
2:处理(2010)=200,将200传递至上一个函数
3:200+(10/10+10)),再处理(10/10+10)这个计算单元
以此推类
有些机智的小伙伴可能已经发现了,在这个递归递推分解算式的过程中,分割的方式是括号优先,而同一个括号中的加减号分割计算的单元
根据这些伪代码思想,可以写出以下js代码
完整代码.需要放在word.js中
var Formula = "(15*10+15)*10";//测试用的算式,实际使用时要置空
var CountRequest = "=";
var CountFormula = [];
window.onload = function (){
//测试用
$("#Countformula").html(Formula);
$("#Result").html(CountRequest);
// 数字处理
$(".Cnumber").click(function(){
var CNumber = $(this).attr("data-event");
Formula = Formula+CNumber;
$("#Countformula").html(Formula);
})
// 验算处理
$(".Count").click(function(){
var CountSymbol = $(this).attr("data-count");
Formula = Formula+CountSymbol;
$("#Countformula").html(Formula);
})
// 计算处理
$(".Dispose").click(function(){
var Dispose = $(this).attr("data-dispose");
switch (Dispose){
case "=":
StartCount();
break;
case "B":
Formula = Formula.substr(0,Formula.length-1);
$("#Countformula").html(Formula);
break;
case "C":
Formula ="";
$("#Countformula").html(Formula);
break;
default:
break;
}
})
// 开始计算
function StartCount(){
//计算
$("#Result").html(GetNumber(CountElement(Formula,0))+"=");
}
// 层次分割器(根据没被括号括起来的+-号分割层次),获得初始的分解块
function LevelCT(CTCount,levelNumber){
var addlevel = 0;
var SPS = 0;//切割的起始位置
var CountList = [];
for(var i = 0;i<=CTCount.length;i++){
if(i==CTCount.length){
//alert(CTCount.substring(SPS));
CountList.push(CTCount.substring(SPS));
break;
}else if(addlevel==levelNumber){
if(CTCount.charAt(i)=="+"||CTCount.charAt(i)=="-"){
//alert(CTCount.substring(SPS,i));
CountList.push(CTCount.substring(SPS,i));
SPS = i;
}
if(CTCount.charAt(i)=="*"||CTCount.charAt(i)=="/"){
CountList.push(CTCount.substring(SPS,i));
SPS = i;
}
}
if(CTCount.charAt(i)=="("){
addlevel++;
}
if(CTCount.charAt(i)==")"){
addlevel--;
}
}
return CountList;
}
//获取数字
function GetNumber(GetString){
var input = GetString + "";
var get = RegExp("\\d","g");
var getnumber = input.match(get);
return getnumber.join("");
}
//递归分解计算
function CountElement(List,levelNumber){
var Symbol = "NULL";
var Sum = [];
var SumNumber = 0;
switch(List.charAt(0)){
case "+":
Symbol = "+";
break;
case "-":
Symbol = "-";
break;
case "*":
Symbol = "*";
break;
case "/":
Symbol = "/";
break;
}
if(Symbol!="NULL"){
List = List.substr(1);
}
var CountFormulaUnit = LevelCT(List,levelNumber);//分解获取的参数,并进行分解
//当该单元长度为1时,说明它无法再分解,是一个数字
if(CountFormulaUnit.length == 1){
var r = GetNumber(CountFormulaUnit)+(Symbol=="NULL"&&"|NULL"||"|"+Symbol);
//document.write("分解:"+r);
return r;
}else{
//循环再分解的每一个单元
//document.write("循环:"+CountFormulaUnit.join(" ")+"<br>");
for(var i = 0;i<CountFormulaUnit.length;i++){
var scanf = CountElement(CountFormulaUnit[i],levelNumber+1).split("|");
switch (scanf[1]){
case "+":
case "-":
case "*":
case "/":
Sum.push(scanf[1]);
Sum.push(scanf[0]);
break;
case "NULL":
Sum.push(scanf[0]);
// SumNumber = parseInt(scanf[0]);
break;
default:
break;
}
}
//document.write("<br>增加:"+Sum.join(""))
//执行乘除法
var MADloca = GetMAD(Sum);
while (MADloca!=-1){
//
//根据计算符号记号
switch (Sum[MADloca]){
case "*":
var MADNumber = parseFloat(Sum[MADloca-1]) * parseFloat(Sum[MADloca+1]);
Sum = SetUnit(Sum,MADNumber,MADloca);
break;
case "/":
var MADNumber = parseFloat(Sum[MADloca-1]) / parseFloat(Sum[MADloca+1]);
Sum = SetUnit(Sum,MADNumber,MADloca);
break;
default:
break;
}
MADloca = GetMAD(Sum);
}
//执行加减法
var CSymbol = "NULL";
if(Sum.length>=1){
SumNumber = parseFloat(Sum[0]);
for(var i = 1;i<Sum.length;i++){
// 递增递减
switch (Sum[i]){
case "+":
CSymbol = "+";
break;
case "-":
CSymbol = "-";
break;
default:
switch (CSymbol){
case "+":
SumNumber += parseFloat(Sum[i]);
CSymbol = "NULL";
break;
case "-":
SumNumber -= parseFloat(Sum[i]);
CSymbol = "NULL";
break;
default:
break;
}
break;
}
}
}
var r = SumNumber+(Symbol=="NULL"&&"|NULL"||"|"+Symbol);
return r;
}
}
//1.操作的对象 2.插入的对象 3.插入的起始位置
function SetUnit(Sum,IObjecgt,Sloca){
var Asum = [];
for(var i = 0;i<Sum.length;i++){
if(i == Sloca){
// 添加代替数组
Asum.push(IObjecgt);
}else if(i>Sloca-2&&i<Sloca+2){
}else{
Asum.push(Sum[i]);
}
}
Sum = Asum;
return Sum;
}
// 获取第一个乘除号的位置
function GetMAD(CountList){
var MPTION = CountList.indexOf("*");
var DIVSION = CountList.indexOf("/");
var MAD = -1;// 第一个乘除法的位置
if(MPTION>DIVSION){
MAD = (DIVSION!=-1&&DIVSION||MPTION);
}else{
MAD = MPTION;
}
//返回计算符号位置
return MAD;
}
}
写在最后
其实我也只是个初学者,在技术方面都是靠自学,基础非常薄弱,厚颜无耻自称老师实属在下脸皮厚.希望这篇浅薄的教程可以帮助一些在前端学习中有些迷茫的同学.学到一些有用的知识.
同时,希望朋友们能够在评论区指出我的错误.共同进步.
我是阿巴阿巴阿巴的潘某人,咱们评论区或者下篇博文再见.古德拜!