android 小玩意儿 关于科学计算器,多则多项多级计算的算法实现

本文主要是介绍android 小玩意儿 关于科学计算器,多则多项多级计算的算法实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

近日学习了android的基本界面和调用,试试写一个科学计算器。虽然还没找到工作,可是貌似工作可遇而不可求啊! 开心就好...


需求:

1.计算器显示输入的表达式

2.支持()运算符

3.支持多次方、三角函数(cos,tan,sin)

4.支持10位π、e

5.支持快速开方

6.支持逻辑运算

7.运算精度和范围(10^-8 - 10^8)

8.支持all_clear快速清理表达式阅览框和结果框,支持del删除表达式最后一个字符


分析:

该计算器的重点不在于如何计算,在于如何把表达式导入计算机交给系统计算。如:输入表达式1+1*2 ,需要对表达式进行分析和求解。

设计解决方案:

   1.使用二叉树的形式用结点存储值  ,按优先级进行中序排序 ,根结点即为最终结果

   2.直接使用数组的形式,对下标进行计算


最终解决方案:


界面设计:




-------算法一 直接使用数组实现(不完整)--------------------------------------------------------------------------------------------------------------------------------------------------------


//分析表达式
/*
* 以+、-、*、/为分割符号 将所有数字取出来 存入数组
* 将所有符号取出来  存入数组
* 遍历符号数组,设置优先级  *、/优先级为1; +,-优先级为0

* 按优先级和数组下标为次序进行计算
*/
private double calculate(StringBuffer expressionStr){
double result=0;
List symbol = new ArrayList();
List<StringBuffer> nums = new ArrayList();


char temp;
boolean flag=false;//判断连续数字
   for(int i=0,index_nums=-1;i<expressionStr.length();i++){
    temp=expressionStr.charAt(i);
    if('+'==temp||'-'==temp||'X'==temp||'/'==temp){
    symbol.add(temp);
    flag=false;
    }else{//('0'==temp||'1'==temp||'2'==temp||'3'==temp||'4'==temp||'5'==temp||'6'==temp||'7'==temp||'8'==temp||'9'==temp||'.'==temp){
   
    if(flag==true){
    nums.get(index_nums).append(temp);
    }else {
    index_nums++;
    nums.add(new StringBuffer(temp+""));
    }
    flag=true;
    }
   }


   
   //将组合的数字字符串每一个转型为double型
   List<Double> nums_dou=new ArrayList();
   for(int i=0;i<nums.size();i++){
    nums_dou.add(Double.valueOf(nums.get(i).toString()));
   }
   
   //开始计算
   //计算方法,采用数组的形式
   List<Double> results = new ArrayList();
   for(int i=0;i<symbol.size();i++){
    results.add(0d);
   }
   for(int i=0;i<symbol.size();i++){
    if(i==0){
    if(symbol.get(i).toString().equals("X")){
    results.set(i, nums_dou.get(i)*nums_dou.get(i+1));
    }
    if(symbol.get(i).toString().equals("/")){
    results.set(i, nums_dou.get(i)/nums_dou.get(i+1));
    }
    if(symbol.get(i).toString().equals("+")){
    results.set(i, Double.valueOf((nums_dou.get(i)+nums_dou.get(i+1))));
    }
    if(symbol.get(i).toString().equals("-")){
    results.set(i, nums_dou.get(i)-nums_dou.get(i+1));
    }
    }else
    if(symbol.get(i).toString().equals("X")||symbol.get(i).toString().equals("/")){
    if(results.get(i-1)==0){
    if(symbol.get(i).toString().equals("X")){
    results.set(i, nums_dou.get(i)*nums_dou.get(i+1));
    }else{
    results.set(i, nums_dou.get(i)/nums_dou.get(i+1));
    }
    }else {
    if(symbol.get(i).toString().equals("X")){
    results.set(i, results.get(i-1)*nums_dou.get(i+1));
    }else{
    results.set(i, results.get(i-1)/nums_dou.get(i+1));
    }
    }
    }else {
    if(results.get(i-1)==0){
    if(symbol.get(i).toString().equals("+")){
    results.set(i, nums_dou.get(i)+nums_dou.get(i+1));
    }else{
    results.set(i, nums_dou.get(i)-nums_dou.get(i+1));
    }
    }else {
    if(symbol.get(i).toString().equals("+")){
    results.set(i, results.get(i-1)+nums_dou.get(i+1));
    }else{
    results.set(i, results.get(i-1)-nums_dou.get(i+1));
    }
    }
    }
    System.out.println("results.get(i)->>"+results.get(i));
    result=results.get(i);
   }
   
   System.out.println("Result->>"+result);
return result;
}




--------------------------我想还是用栈或者二叉树比较好实现点----------


因为java中没有栈这种数据结构,那么只能模拟了。这里我使用数组来模拟栈


package tk.orangers.calculate;


//利用数组实现简单的堆栈
public class arrayStact {
private int pointcounter;// 栈指针
double[] stact = new double[100];


public arrayStact() {
for (int i = 0; i < stact.length; i++)
stact[i] = -1;
pointcounter = 0;
}


public void push(double temp) {
pointcounter++;


if (pointcounter < 100) {
for (int i = pointcounter; i > 0; i--)
stact[i] = stact[i - 1];
stact[0] = temp;


} else
System.out
.println("Error:表达式长度超过了栈大小~!\n");
}


public double pop() {
double temptop = -1;
if (isEmpty()) {
System.out.println("Error:栈是空的!\n");
} else {
temptop = stact[0];
for (int i = 0; i < pointcounter; i++)
stact[i] = stact[i + 1];


pointcounter--;
}
return temptop;
}


public double gettop() {
return stact[0];
}


private boolean isEmpty() {
if (pointcounter == 0)
return true;
else
return false;
}
}



分析字符串表达式,将字符串中的数字与符号分割开来

之后分别使用两个栈来存放运算符号和运算者

关于优先级,借鉴了数据结构中的验证矩阵来求解

根据符号优先级,依据符号栈进行计算



package tk.orangers.calculate;


public class stringAnalysis{
arrayStact stact_nums = new arrayStact();// 存放操作数
arrayStact stact_symbol = new arrayStact();// 存放运算符号
String[] unit = new String[200]; // 存放解析出来的操作数与运算符
int[][] priority = { // + - * / ( ) 优先级比较矩阵
{ 2, 2, 1, 1, 1, 2, 2 }, 
{ 2, 2, 1, 1, 1, 2, 2 }, 
{ 2, 2, 2, 2, 1, 2, 2 },
{ 2, 2, 2, 2, 1, 2, 2 }, 
{ 1, 1, 1, 1, 1, 0, 3 },
{ 2, 2, 2, 2, 3, 2, 2 }, 
{ 1, 1, 1, 1, 1, 3, 0 },
};
// 0表示相等 1表示小于 2表示大于 3表示错误
// + 用0表示,- 用1表示,* 用2表示,/ 用3表示,
// ( 用4表示,) 用5表示,# 用6表示
//横与纵的关系 如:第一行第三列为1 表示+的优先级小于*
private String temp;// 用于构造函数
private int arraypoint = 0;// 记录unit数组的存储长度


private int i = 0;// 读取unit数组的元素


private String tempstring;// 保存临时unit的值


private int start = 0; // 数字字符串开始位置


private int counter = 0; // 字符个数计数


private int target = 0; // 保存开始计数位置


private int lab = 1; // 表示计数结束输出数串


private int index = 0; // 表示字符串读取位置的计数


private int iscorrect = 1;// 表示是否继续读取整个字符串到存放数组(表示是是否是正确地表达式),1表示继续,0表示停止


private int isrecord = 0;// 表示是否存入数组,1表示存入数组合,0表示不存入数组


private int isnext = 1; // 表示检测每一个数组单元值,如果非法为0,不非法为1(即进行下一步)


private int leftbracket = 0, rightbracket = 0;// 左,右括号记数目

private double result=0d;//结果

   public double getResult( ){//计
  return this.result;
   }
public stringAnalysis(String passtemp) {
this.temp = passtemp;
processwhitespace();
processexpression();


if (leftbracket != rightbracket) {
isnext = 0;
System.out
.println("Erro:括号不对称哦~~!");
}


if (isnext == 1)
computeexpression();
}


private void processwhitespace() {//将表达式剔除空格 
String emptystring = "";
String[] tempstring = temp.split(" ");
for (int i = 0; i < tempstring.length; i++) {
emptystring += tempstring[i];
}


System.out.println("Log:被计算的表达式是:\n" + emptystring);
System.out.println("\n");


temp = emptystring + "#";
stact_symbol.push(6);// 初始化操作符堆栈
}


private void partprocessexpression(String tempstringtemp) {
if (iserrorexpression(tempstringtemp))
isnext = 0;
else {
if (tempstringtemp == "-" && index == 0)
isrecord = 1;
else if (temp.charAt(index - 1) == ')') {
unit[arraypoint] = tempstringtemp;
arraypoint++;
} else {
lab = 1;
if (lab == 1) {
target = 0;
lab = 0;


if (counter == 0)
;// ()时候移位
else {
if (isrecord == 1) {
unit[arraypoint] = "-"
+ temp.substring(start, start + counter);// 开始第一位为负数
arraypoint++;
isrecord = 0;
} else {
unit[arraypoint] = ""
+ temp.substring(start, start + counter);
arraypoint++;
}
}
counter = 0;
}


unit[arraypoint] = tempstringtemp;
arraypoint++;
}// end inner else
}// end outer else
}


private void processexpression()// 读取表达式,将预算符号与操作数分开,并存入数组
{
for (; index < temp.length(); index++) {
switch (temp.charAt(index)) {
case '(':
if (iserrorexpression("("))
isnext = 0;
else {
leftbracket++;
unit[arraypoint] = "(";
arraypoint++;
if (temp.charAt(index + 1) == '-'&& temp.charAt(index + 2) - '0' >= 1&& temp.charAt(index + 2) - '0' <= 9) {
int end = 0;
for (int tempm = index + 1; tempm < temp.length(); tempm++) {
if (temp.charAt(tempm) == ')') {
end = tempm;
break;
}
}
unit[arraypoint] = temp.substring(index + 1, end);
arraypoint++;
index = end - 1;
target = 0;
lab = 0;
counter = 0;
}
}// end else
break;
case ')':
if (index == 0)
isnext = 0;
else {
partprocessexpression(")");
rightbracket++;
}
break;
case '+':
if (index == 0)
isnext = 0;
else
partprocessexpression("+");
break;
case '-':
partprocessexpression("-");
break;
case '*':
if (index == 0)
isnext = 0;
else
partprocessexpression("*");
break;
case '/':
if (index == 0)
isnext = 0;
else
partprocessexpression("/");
break;
case '#':
unit[arraypoint] = "#";
break;
default:
if (target == 0) {
start = index;
lab = 0;
target = 1;
}
if (lab == 0)
counter++;
if (start + counter == temp.length() - 1) {
unit[arraypoint] = ""+ temp.substring(start, start + counter);
arraypoint++;


}
}// end switch
}// edn for
}// end processexpression


private boolean iserrorexpression(String errortempstring) {//检查表达式错误
boolean iserror = false;


switch (errortempstring.charAt(0)) {
case '(':
if (temp.charAt(index - 1) == ')'
|| temp.charAt(index + 1) == ')'
|| (temp.charAt(index - 1) >= '0' && temp.charAt(index - 1) <= '9'))


iserror = true;
break;
case ')':
if (temp.charAt(index - 1) == '('
|| temp.charAt(index + 1) == '('
|| (temp.charAt(index + 1) >= '0' && temp.charAt(index + 1) <= '9'))


iserror = true;
break;
case '+':
case '*':
case '/':
if (temp.charAt(index - 1) == '(' || temp.charAt(index - 1) == '+'
|| temp.charAt(index - 1) == '-'
|| temp.charAt(index - 1) == '*'
|| temp.charAt(index - 1) == '/'
|| temp.charAt(index + 1) == ')'
|| temp.charAt(index + 1) == '+'
|| temp.charAt(index + 1) == '-'
|| temp.charAt(index + 1) == '*'
|| temp.charAt(index + 1) == '/')//符号重复性检查


iserror = true;
break;
case '-':
if (index != 0) {
if (temp.charAt(index - 1) == '+'
|| temp.charAt(index - 1) == '-'
|| temp.charAt(index - 1) == '*'
|| temp.charAt(index - 1) == '/'
|| temp.charAt(index + 1) == ')'
|| temp.charAt(index + 1) == '+'
|| temp.charAt(index + 1) == '-'
|| temp.charAt(index + 1) == '*'
|| temp.charAt(index + 1) == '/'){//针对-号的处理  考虑负数情况


iserror = true;
}
if (temp.charAt(index - 1) == '(') {
if (temp.charAt(index + 1) - '0' >= 1
&& temp.charAt(index + 1) - '0' <= 9)
iserror = false;
else


iserror = true;


}
} else {
if (temp.charAt(index + 1) == ')'
|| temp.charAt(index + 1) == '+'
|| temp.charAt(index + 1) == '-'
|| temp.charAt(index + 1) == '*'
|| temp.charAt(index + 1) == '/')


iserror = true;
}
break;
default:
System.out.println("Error6 at" + (index - 1) + "~~" + (index + 1));


}// end switch


return iserror;
}


private void computeexpression() {//计算
tempstring = unit[i];


while (tempstring != "#" || stact_symbol.gettop() != 6) {//遍历unit
if (tempstring != "+" && tempstring != "-" && tempstring != "*"&& tempstring != "/" && tempstring != "("&& tempstring != ")" && tempstring != "#") {
stact_nums.push(Double.parseDouble(unit[i]));//数字入栈
tempstring = unit[++i];
} else {
switch (tempstring.charAt(0)) {//符号入栈 并根据符号优先级进行计算
case '+':
compareandprocess(0);
break;
case '-':
compareandprocess(1);
break;
case '*':
compareandprocess(2);
break;
case '/':
compareandprocess(3);
break;
case '(':
compareandprocess(4);
break;
case ')':
compareandprocess(5);
break;
case '#':
compareandprocess(6);
break;
}// end switch
} // end else
}// end while
}


private void compareandprocess(int a) {
switch (priority[(int)stact_symbol.gettop()][a]) {//优先级验证
case 0:  //优先级相等
stact_symbol.pop();
tempstring = unit[++i];
break;
case 1://优先级小于
stact_symbol.push(a);
tempstring = unit[++i];
break;
case 2://优先级大于当前栈顶符号  则计算
partcompareandprocess();
break;
case 3: {//错误 不可比较的错误
System.out.println("error~!");
System.out.println(stact_symbol.gettop() + "  " + a);
}
}
}


private void partcompareandprocess() {
double tempa, tempb, tempc;
int tempoperator;
tempoperator = (int)stact_symbol.pop();
tempb = stact_nums.pop();
tempa = stact_nums.pop();


switch (tempoperator) {
case 0:
tempc = tempa + tempb;
stact_nums.push(tempc);
result=tempc;
break;
case 1:
tempc = tempa - tempb;
stact_nums.push(tempc);
result=tempc;
break;
case 2:
tempc = tempa * tempb;
stact_nums.push(tempc);
result=tempc;
break;
case 3:
tempc = tempa / tempb;
stact_nums.push(tempc);
result=tempc;
break;
}
}
}



待续...

这篇关于android 小玩意儿 关于科学计算器,多则多项多级计算的算法实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/475120

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo