200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 计算器小程序技术要求C语言 小程序简单计算器实现思路

计算器小程序技术要求C语言 小程序简单计算器实现思路

时间:2021-05-17 18:44:41

相关推荐

计算器小程序技术要求C语言 小程序简单计算器实现思路

好久不写了,这回又是点最近业务相关的😂。这篇断断续续也写了三个月(喂!)

要在小程序上做个小程序,整个重点分成2个部分:

1、输入控制;

2、算式计算。

输入控制是为了保证我们最后计算的算式是个合法算式。而算式计算,因为eval的不安全性,小程序把该方法禁用了,我们得自己实现简单的‘+-*/’。如图:

输入控制:

我们把算式分成两个,一个是真实的用于计算的算式,另一个是显示用的给用户观看的便于理解的算式。

真实的算式:

保证算式第一位是数字,如果输入的是符号,在前面补零;

保证最后一位是数字,如果不是抛出错误提示

保证算式形式是'数字-符号-数字'形式,当输入符号时,当前最后一位如果也是符号,则替换

如果当前是初始默认的0,如果首次输入为数字则替换为真实输入。

显示的算式:

替换'*'、'/'符号,变成方便观看的'×'、'÷';

首位如果输入了符号,再前面补零;

当输入时,真实的算式和显示的算式一起变动,保证算式合法有效。

算式计算

以下拿“2+5*6-10”为例子。

大概思想是,格式化得到的有效算式字符串,以符号为分割基准,将算式分割成有效数字和符号部分,如:

"2+5*6-10" => ['2', '+', '5', '*', '6', '-', '10']

复制代码

再遍历所得字符串,按优先级计算,把算式中的计算分割成最小式子进行计算。

1.先写个计算函数,用于简单的'+-*/'计算。

/*

* @param sign 计算符号

* @param num1 输入数字1

* @param num2 输入数字2

*/

signCompute(sign:string, num1:number, num2:number): number {

switch(sign){

case '+':

return num1 + num2;

case '-':

return num1 - num2;

case '*':

return Math.round(num1 * num2);

case '/':

return Math.round(num1 / num2);

default:

return num1

}

}

复制代码

2.将扁平的算式字符串变成有效数组,符号间的字符转换成数字。

/*

* 将算式字符串转化成有效的数组

* @param formula 一个合法的字符串算式

*/

formulaToArray(formula: string) {

const length = formula.length

let str = '' // 储存字符,如果遇到的是符号,则将存好的字符串push进数组

const regex = /[*\/+-]/ // 是否是符号判断

const formulaList = [] // 最后需要返回的正确数组

for (let index=0; index < length; index++){ // 开始遍历字符串

const item = formula[index]

// 如果当前元素是符号,则将str中存储的数字和当前符号push进数组中,并清空str,进入下一轮循环。

if (regex.test(item)) {

formulaList.push(str)

formulaList.push(item)

str = ''

continue

}

// 当前字符非符号时,将当前字符并入str中

str += item

// 当前字符为最后一个字符,将str存储的字符push入数组

if (index == length - 1) formulaList.push(str)

}

return formulaList

}

复制代码

3.遍历2得到的合法算式数组,进行计算。

若只进行“+-*/”计算,算式的优先级分为2个,因此要遍历两次:

第一次先将第一优先级的进行乘除计算。从左到右遍历字数组,遇到乘除算式进行计算,并将结果替换掉原本的算式位置。例如:第一次遍历先计算“5*6”,得出结果30,将原等式变为“2+30-10”。

第二次遍历,从左到右将第二优先级的“+-”进行计算。“2+30-10” ➡️ “32-10” ➡️ “22”。

如遇到不合法的参数,则将错误进行抛出,后续将在外层进行捕获。

/*

* @param list 算式数组

*/

computeHasPriority(list: Array) {

// 第一次遍历,计算第一优先级

for (let index = 0; index < list.length; index++) {

const item = list[index]

const preIndex = index - 1 // 指向前一个字符的下标

const lastIndex = index + 1 // 指向后一个字符的下标

// 如果当前元素不是“*”或“/”,则结束当前循环

if (item !== '*' && item !== '/') continue

// 除数为0抛出错误

if (item == '/' && list[lastIndex] == '0') throw new Error('除数不能为0哦')

// 计算,得到值(当前index指向的是符号未)

const res = this.signCompute(item, Number(list[preIndex]), Number(list[lastIndex]))

// 将符号位的后一个字符替换为得到的算式值

list[lastIndex] = res.toString()

// 删除符号位和符号位前的字符

list.splice(preIndex, 2)

// 当前index向前移两位,重新指向刚刚得到的算式值

index = index - 2

}

// 第二次遍历计算第二优先级,如需计算则直接返回结果

for (let index = 0; index < list.length; index++) {

const item = list[index]

const preIndex = index - 1

const lastIndex = index + 1

// 如果当前元素不是“+”或“-”,则结束当前循环

if (item !== '+' && item !== '-') continue

const res = this.signCompute(item, Number(list[preIndex]), Number(list[lastIndex]))

list[lastIndex] = res.toString()

// 如果符号位后一个字符位置是最后一个,则直接返回计算结果

if (lastIndex == list.length - 1) return res.toString()

// 删除符号位和符号位前的字符

list.splice(preIndex, 2)

// 当前index向前移两位,重新指向刚刚得到的算式值

index = index - 2

}

// 如果算式只有一位数 直接返回该数

if (list.length == 1) return Number(list[0])

else return 0

}

复制代码

使用

const formula = '2+5*6-10'

const formulaList = formulaToArray(formula)

try{

const result = computeHasPriority(formulaList)

return true

}catch(e) {

console.log(e)

this.setData({ error: '您的算式不正确哦' })

return false

}

复制代码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。