zoukankan      html  css  js  c++  java
  • 重新整理数据结构与算法——一个简单的计算器[七]

    前言

    一段往事:

    那就事当年学winform的时候老师布置了一个计算器的东西,但是当时对计算机的热情过于强烈,所以呢,不懂什么是算法结构,直接按照自己的思维开干。

    我就不讲当时if else 的思维了,只讲当时自己想出的思维,想的其实像一个栈,但是呢,不是用栈实现的,这里用栈实现一下。

    正文

    思路:

    1.将数字的栈和符号的栈分开

    2.当符号栈中要进入的符号比栈中符号的优先级大的话,直接进入栈中。

    如果优先级小于或者等于优先级的话,在数字栈中弹出两个数字,进行计算放入到符号栈中。

    3.最后每次弹出两个数字和一个符号进行计算。

    这个思路是网上大把有,但是以前自己能想出来也是感觉可以的。

    最难理解的就是第二点了。

    看图:

    722-5+1

    假如要计算这个,那么当7 2 2入数字栈后,-入符号栈的时候,那么这个时候怎么破?

    这时候就应该弹出,然后计算22。

    其实上面有问题,当符号第二个的时候其实就应该计算第一个的,上面只是作为一个演示。

    那么就来改一下重新整理数据结构与算法——一个简单拿的计算器[六] 中的栈吧。

    代码

    public class ArrayStack
    {
    	public int MaxLen;
    
    	public int[] Arr;
    
    	// 设置栈顶
    	public int top = -1;
    
    	public ArrayStack(int MaxLen) {
    		this.MaxLen = MaxLen;
    		Arr = new int[MaxLen];
    	}
    	/// <summary>
    	/// 判断是否为空
    	/// </summary>
    	/// <returns></returns>
    	public bool isEmpty(){
    		return top == -1;
    	}
    	/// <summary>
    	/// 判断是否满了
    	/// </summary>
    	/// <returns></returns>
    	public bool isFull() {
    		return top == MaxLen - 1;
    	}
    	/// <summary>
    	/// 放入元素
    	/// </summary>
    	public void push(int ele)
    	{
    		if (isFull())
    		{
    			throw new Exception("栈满了");
    		}
    		top++;
    		Arr[top] = ele;
    	}
    
    	public int pull() {
    		if (isEmpty())
    		{
    			throw new Exception("栈为空");
    		}
    		int reult=Arr[top];
    		top--;
    		return reult;
    	}
    
    	public int showTop() {
    		if (isEmpty())
    		{
    			throw new Exception("栈为空");
    		}
    		return Arr[top]; 
    	}
    
    	public void showStack()
    	{
    		if (isEmpty())
    		{
    			return;
    		}
    		for (int i = top; i >= 0; i--)
    		{
    			Console.WriteLine(Arr[top]);
    		}
    	}
    	/// <summary>
    	/// 定级
    	/// </summary>
    	/// <param name="oper"></param>
    	/// <returns></returns>
    	public int priority(int oper)
    	{
    		if (oper == '/' || oper == '*')
    		{
    			return 1;
    		}
    		else if (oper == '+' || oper == '-')
    		{
    			return 0;
    		}
    		else {
    			throw new Exception("特殊不明符号");
    		}
    	}
    	/// <summary>
    	/// 判断是否为字符
    	/// </summary>
    	/// <param name="val"></param>
    	/// <returns></returns>
    	public bool isOper(char val)
    	{
    		//同样可以通过对应码判断
    		return val == '+' || val == '-' || val == '*' || val == '/';
    	}
    	/// <summary>
    	/// 进行计算
    	/// </summary>
    	/// <param name="num1"></param>
    	/// <param name="num2"></param>
    	/// <param name="oper">操作符号</param>
    	/// <returns></returns>
    	public int cal(int num1, int num2, int oper)
    	{
    		int res=0;
    		switch (oper)
    		{
    			case '+':
    				res = num1 + num2;
    				break;
    			case '-':
    				res = num1 - num2;
    				break;
    			case '*':
    				res = num1 * num2;
    				break;
    			case '/':
    				res = num1 / num2;
    				break;
    		}
    		return res;
    	}
    }
    

    测试:

    static void Main(string[] args)
    {
    	//根据前面老师思路,完成表达式的运算
    	String expression = "16*16";
    	ArrayStack numsStack = new ArrayStack(10);
    	ArrayStack operStack = new ArrayStack(10);
    	char ch = ' '; //将每次扫描得到char保存到ch
    	string temp = "";
    	int index = 0;
    	int num2;
    	int num1;
    	//先装栈
    	while (true)
    	{
    		ch = expression.Substring(index, 1).ToCharArray()[0];
    		if (operStack.isOper(ch))
    		{
    			//处理数字
    			if (temp != "")
    			{
    				numsStack.push(Convert.ToInt32(temp));
    				temp = "";
    			}
    			if (operStack.isEmpty())
    			{
    				operStack.push(ch);
    			}
    			else
    			{
    				if (operStack.priority(ch) <= operStack.priority(operStack.showTop()))
    				{
    					num2 = numsStack.pull();
    					num1 = numsStack.pull();
    					numsStack.push(numsStack.cal(num1, num2, operStack.pull()));
    				}
    				operStack.push(ch);
    			}
    		}
    		else
    		{
    			//考虑是否是多位数
    			temp += ch;
    			//只处理ch为最后一位的情况,数字入栈让符号位去判断
    			if (index == expression.Length - 1)
    			{
    				numsStack.push(Convert.ToInt32(temp));
    				temp = "";
    			}
    		}
    		index++;
    		if (index >= expression.Length)
    		{
    			break;
    		}
    	}
    	int oper;
    	int sum;
    	while (true)
    	{
    		if (operStack.isEmpty())
    		{
    			break;
    		}
    		num2 = numsStack.pull();
    		num1 = numsStack.pull();
    		numsStack.push(numsStack.cal(num1, num2, operStack.pull()));
    	}
    	Console.WriteLine("最终结果位:"+numsStack.showTop());
    	Console.ReadKey();
    }
    

    下一步

    逆波兰计算器

  • 相关阅读:
    XML(学习笔记)
    css样式学习笔记
    Request(对象)
    sql一些错误修改的总结
    转载(如何学习C#)
    sql server(学习笔记2 W3Cschool)
    sql sqrver(学习笔记1 W3Cschool)
    关于 flutter开发碰到的各种问题,有的已经解决有的一直没解决或者用其他方法替代
    关于 Flutter IOS build It appears that your application still contains the default signing identifier.
    关于 flutter本地化问题 The getter 'pasteButtonLabel' was called on null
  • 原文地址:https://www.cnblogs.com/aoximin/p/13100678.html
Copyright © 2011-2022 走看看