数据结构-大作业-计算器
源码及源文件及计算器本体下载地址:https://download.csdn.net/download/qq_33911878/20008183?spm=1001.2014.3001.5501
- 实验目的和要求
实现可视化图形交互界面的计算器
二、实验环境
Vs2019
Unity 2020
R7000p
三、实验内容
实现可视化图形交互界面的计算器,完成各个计算器功能,+。-。*。/。&&。||。!等运算
- 实验过程
设计计算器界面,这里我使用游戏引擎Unity设计计算器图形界面并且完成各个按钮功能
计算器核心代码是有实验报告-03的计算器代码更改添加而成。
4.2 数据结构的选择和概要设计
使用俩个栈实现计算器的计算功能
图形设计部分,我使用了部分网络图片素材,作为按钮,使计算器美化,同时我也给按钮加入了音效,计算器整体使用观感会更好。
4.3 详细设计
图形界面如图,
点击狗头按钮可以更换按钮,出现&&,||,!运算符
当发生计算错误时,结果变成狗头图标。
五、测试及结果分析
5.1 实验数据
5.2 结果及分析
各种计算错误均已处理,结果返回狗头图标,表示计算式输入错误。
- 实验收获
之前计算器实现代码使用的是C++语言,但是游戏引擎Unity使用的是C#语言,临时学了一下,把实验作业-03代码转换为C#语言后部分修改,复用代码,作为计算器核心。
个人感觉学过C++后,学其他语言的确很快。
图形设计部分,我使用了部分网络图片素材,作为按钮,使计算器美化,同时我也给按钮加入了音效,计算器整体使用观感会更好。
源程序已经打包,并且借用unity跨平台特性,可以生产手机安卓,Ios端,电脑端等多端程序。
源程序随附件,,附上,可以在任意电脑上运行。
按ESC键退出程序。
- 参考文献
C#语言学习视频
八、附录(源代码)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
class CACULATOR : NewBehaviourScript
{
public Stack<double> nums = new Stack<double>();
public Stack<char> caltor = new Stack<char>();
//运算函数
int Count(char b)
{
int Peek = Judge(caltor.Peek());
//-1级和3级运算符不进行真正计算
if (Peek == -1 && b == '=')
{
return 0;
}
if (Peek == 3 && b == ')')
{
caltor.Pop();
return 0;
}
if (Peek == 3)
{
caltor.Push(b);
return 0;
}
//真正计算过程,计算完成后弹出栈顶运算字符,返回1表示运算成功
double x = 0;
double y = 0;
if (Peek != 4)
{
if (nums.Count < 2) return -1;
x = nums.Peek();
nums.Pop();
y = nums.Peek();
nums.Pop();
}
else
{
if (nums.Count < 1) return -1;
x = nums.Peek();
nums.Pop();
}
//根据级别运算
if (Peek == 0)
{
if (caltor.Peek() == '1')
{
if (x == 0 && y == 0) { nums.Push(0); }
else { nums.Push(1); }
}
if (caltor.Peek() == '7')
{
if (x == 0 || y == 0) { nums.Push(0); }
else { nums.Push(1); }
}
}
if (Peek == 1)
{
if (caltor.Peek() == '-') nums.Push(y - x);
if (caltor.Peek() == '+') nums.Push(y + x);
}
if (Peek == 2)
{
if (caltor.Peek() == '/')
{
if (x == 0) return 0;
nums.Push(y / x);
}
if (caltor.Peek() == '*') nums.Push(y * x);
}
if (Peek == 4)
{
if (caltor.Peek() == '!')
{
if (x == 0) nums.Push(1);
if (x != 0) nums.Push(0);
}
}
//弹出栈顶运算符
if (caltor.Count < 1) return -1;
caltor.Pop();
return 1;
}
//运算符级别判断
int Judge(char a)
{
if (a == '=') return -1;
if (a == ')') return -1;
if (a == '1') return 0;
if (a == '7') return 0;
if (a == '+') return 1;
if (a == '-') return 1;
if (a == '*') return 2;
if (a == '/') return 2;
if (a == '(') return 3;
if (a == '!') return 4;
return -1;
}
//字符转数字函数
double To_Numbers(ref int i, ref string cal)//传入数字字符最开始位置,和字符串
{
string num = "";
while (i < cal.Length && cal[i] - 48 >= 0 && cal[i] - 48 < 10)
{
num += (cal[i]);
i++;
}
i--;
return double.Parse(num);
}
//计算读入返回最终结果函数
double Calculator(ref string cal,ref bool f)
{
caltor.Push('=');
for (int i = 0; i < cal.Length; i++)
{
//当前读取是数字
if (cal[i] - 48 >= 0 && cal[i] - 48 < 10)
{
nums.Push(To_Numbers(ref i, ref cal));
}
else
{
int Peek = Judge(caltor.Peek());
int b = 0;
if (i < cal.Length - 1 && (cal[i] == '&' && cal[i + 1] == '&')) { b = 0; }
else if (i < cal.Length - 1 && (cal[i] == '|' && cal[i + 1] == '|')) { b = 0; }
else b = Judge(cal[i]);
//当前读取是运算符,大于栈顶直接放入,小于或者等于则先计算前者
if (b >= Peek || Peek == 3)
{
if (i < cal.Length - 1 && (cal[i] == '&' && cal[i + 1] == '&')) { caltor.Push('7'); i++; }
else if (i < cal.Length - 1 && (cal[i] == '|' && cal[i + 1] == '|')) { caltor.Push('1'); i++; }
else { caltor.Push(cal[i]); }
}
else
{
int c = 1;
while (b <= Judge(caltor.Peek()))
{
//传入即将放入的运算符,以便判断是否需要特殊计算
c = Count(cal[i]);
if (c == -1) { f = false; return 0; }
if (c == 0)
{
break;
}
}
if (c == 1) caltor.Push(cal[i]);
}
}
}
if (nums.Count!=0) return nums.Peek();
f = false;
return 0;
}
//计算界面函数
public CACULATOR() { }
public double Calculate(ref string s,ref bool f)
{
double x= Calculator(ref s,ref f);
return x;
}
};
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
int s = 20;
public GameObject back;
public GameObject equal;
public GameObject Clear;
public GameObject and;
public GameObject huo;
public GameObject fei;
public GameObject dog1;
public AudioSource anjian,dog;
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home))
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
public void updata(string numbers)
{
gameObject.GetComponent<TMP_Text>().text += numbers;
anjian.Play();
if (gameObject.GetComponent<TMP_Text>().text.Length >= s)
{
gameObject.GetComponent<TMP_Text>().fontSize /= 2;
s *= 2;
}
}
public void calculator()
{
bool f = true;
CACULATOR calculator=new CACULATOR();
anjian.Play();
string s = gameObject.GetComponent<TMP_Text>().text;
double x = calculator.Calculate(ref s, ref f);
if(f==false)
{
Setdog();
}
else
{
updata(x.ToString());
}
}
public void pop()
{
anjian.Play();
if (dog1.activeSelf == true) dog1.SetActive(false);
int k = gameObject.GetComponent<TMP_Text>().text.Length;
if(k==0)
{
return;
}
string s= gameObject.GetComponent<TMP_Text>().text.Substring(0,k-1);
gameObject.GetComponent<TMP_Text>().text=s;
}
public void clear()
{
anjian.Play();
if (dog1.activeSelf == true) dog1.SetActive(false);
gameObject.GetComponent<TMP_Text>().text = "";
}
public void Setactive()
{
dog.Play();
if (back.activeSelf == true)
{
back.SetActive(false);
equal.SetActive(false);
Clear.SetActive(false);
and.SetActive(true);
huo.SetActive(true);
fei.SetActive(true);
}
else
{
back.SetActive(true);
equal.SetActive(true);
Clear.SetActive(true);
and.SetActive(false);
huo.SetActive(false);
fei.SetActive(false);
}
}
public void Setdog()
{
clear();
dog1.SetActive(true);
}
}