C#数据结构与算法系列(九):栈实现综合计算器(中缀表达式)
1.问题介绍

2.实现思路

3.代码实现
第一个版本(采用这个)
public class ArrayStack
{
private int _maxSize;
private int[] _arr;
private int _top = -; /// <summary>
/// 初始化栈
/// </summary>
/// <param name="maxSize"></param>
public ArrayStack(int maxSize)
{
_maxSize = maxSize;
_arr = new int[_maxSize];
} /// <summary>
/// 栈是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty() => _top == -; /// <summary>
/// 栈是否满
/// </summary>
/// <returns></returns>
public bool IsFull() => _top == _maxSize-; /// <summary>
/// 入栈
/// </summary>
/// <param name="value"></param>
public void Push(int value)
{
if (IsFull())
{
Console.WriteLine("栈满");
}
else
{
_top++;
_arr[_top] = value;
}
}
/// <summary>
/// 出栈
/// </summary>
/// <returns></returns>
public int Pop()
{
if (IsEmpty())
{
throw new Exception("栈空");
}
int value = _arr[_top]; _top--; return value;
} /// <summary>
/// 栈列表
/// </summary>
public void List()
{
if (IsEmpty())
{
Console.WriteLine("栈空");
}
else
{
for (int i = _top; i >= ; i--)
{
Console.WriteLine($"stack:[{i}]={_arr[i]}");
}
}
} /// <summary>
/// 返回当前栈顶的值
/// </summary>
/// <returns></returns>
public int Peek() => _arr[_top]; /// <summary>
/// 优先级判断
/// </summary>
/// <param name="oper"></param>
/// <returns></returns>
public int Priority(int oper)
{
if (oper == '*' || oper == '/')
{
return ;
}
else if (oper == '+' || oper == '-')
{
return ;
}
else return -;
}
/// <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 result = ;
switch (oper)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num2 - num1; //注意顺序
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1; //注意顺序
break;
default:
break;
}
return result;
} /// <summary>
/// 判断是否是操作符
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public bool IsOper(char val)
{
return val == '-' || val == '+' || val == '*' || val == '/';
}
}
using System; namespace DataStructure
{
public class Calculator
{
public static void Test()
{
string expression = "300+2*3+2-1"; ArrayStack numStack = new ArrayStack(); ArrayStack operStack = new ArrayStack(); //把字符串转换成char数组
char[] arr = expression.ToCharArray(); /*
public unsafe char[] ToCharArray() int length = this.Length;
char[] array = new char[length];
if (length > 0)
{
fixed (char* ptr = &this.m_firstChar)
{
fixed (char* ptr2 = array)
{
string.wstrcpy(ptr2, ptr, length);
}
}
}
return array; */
//结果
int result = ; int num1 = ; int num2 = ; int oper = ; string keepNum = ""; for (int i = ; i < arr.Length; i++)
{
//判断是不是操作符
if (operStack.IsOper(arr[i]))
{
//如果不是空的
if (!operStack.IsEmpty())
{
//如果符号栈中有操作符,就进行比较,如果当前操作符的优先级小于或等于栈中的操作符,就需要从栈中pop出两个数
//再从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后再把当前操作符入符号栈
if (operStack.Priority(arr[i]) <= operStack.Priority(operStack.Peek()))
{
num1 = numStack.Pop(); num2 = numStack.Pop(); oper = operStack.Pop(); //计算
result = numStack.Cal(num1, num2, oper); numStack.Push(result); operStack.Push(arr[i]);
}
else
{
//如果当前操作符的优先级大于栈中的操作符就直接入符号栈
operStack.Push(arr[i]);
}
}
else
{
//为空就直接入符号栈
operStack.Push(arr[i]);
}
}
else
{
//把字符转成字符串
keepNum += arr[i]; for (int j = i + ; j < arr.Length; j++)
{
//判断arr[i]的面是否是操作符 如果不是则拼接
if (!numStack.IsOper(arr[j]))
{
keepNum += arr[j]; i++;//当确定后一个是数字的时候 索引也要跟着往后移
}
//如果是则终止
else break;
} numStack.Push(int.Parse(keepNum)); //一定要置空,否则会保留上一次操作
keepNum = "";
}
}
//当数字占和符号栈都不为空的情况下才进循环
while (!operStack.IsEmpty() && !numStack.IsEmpty())
{
//当符号栈为空的时候就跳出循环
if (operStack.IsEmpty()) break; num1 = numStack.Pop(); num2 = numStack.Pop(); oper = operStack.Pop(); result = numStack.Cal(num1, num2, oper); numStack.Push(result);
} Console.WriteLine($"表达式{expression}={numStack.Pop()}");
}
}
}
第二个版本
public class ArrayStack {
private int maxSize;
private int[] stack;
private int top = -1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == maxSize;
}
public void push(int value) {
if (isFull()) {
System.out.println("栈已满!");
} else {
top++;
stack[top] = value;
}
}
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈为空");
}
int result = stack[top];
top--;
return result;
}
public void list() {
if (isEmpty()) {
System.out.println("栈为空");
} else {
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d]=%d\n", i, stack[i]);
}
}
}
public int peek() {
return stack[top];
}
public boolean isOperate(int vaule) {
return vaule == '*' || vaule == '/' || vaule == '+' || vaule == '-';
}
public int calculate(int num1, int num2, int operate) {
switch (operate) {
case '*':
return num1 * num2;
case '/':
return num2 / num1;
case '+':
return num1 + num2;
case '-':
return num2 - num1;
default:
return 0;
}
}
public int priority(int operate) {
if (operate == '*' || operate == '/') {
return 1;
} else if (operate == '+' || operate == '-') {
return 0;
} else return -1;
}
}
public class Calculator {
public static void main(String[] args) {
String expression = "3+2*5-1";
ArrayStack numStack = new ArrayStack(10);
ArrayStack operateStack = new ArrayStack(10);
int num1, num2, operate, result;
int index = num1 = num2 = operate = result = 0;
char value;
while (true) {
value = expression.substring(index, index + 1).charAt(0);
if (operateStack.isOperate(value)) {
if (operateStack.isEmpty()) {
operateStack.push(value);
} else {
if (operateStack.priority(value) <= operateStack.priority(operateStack.peek())) {
num1 = numStack.pop();
num2 = numStack.pop();
operate = operateStack.pop();
result = operateStack.calculate(num1, num2, operate);
numStack.push(result);
operateStack.push(value);
} else {
operateStack.push(value);
}
}
} else {
String keepNum = "" + value;
if (index == expression.length() - 1) {
numStack.push(Integer.parseInt(keepNum));
break;
} else {
char nextNum = expression.substring(index + 1, index + 2).charAt(0);
if (operateStack.isOperate(nextNum)) {
numStack.push(Integer.parseInt(keepNum));
} else {
keepNum += nextNum;
numStack.push(Integer.valueOf(keepNum));
keepNum = "";
}
}
}
index++;
}
while (true) {
if (operateStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
operate = operateStack.pop();
result = operateStack.calculate(num1, num2, operate);
numStack.push(result);
}
System.out.printf("\n%s的结果是%d", expression, numStack.pop());
}
}
C#数据结构与算法系列(九):栈实现综合计算器(中缀表达式)的更多相关文章
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解
数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...
- C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611
09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...
- C#数据结构与算法系列(八):栈(Stack)
1.介绍 栈是一个先入后出(FILO-First In Last Out)的有序列表 栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的特殊线性表.允许插入和删除的一端,为变化的一端,称为栈顶 ...
- JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝
前言 想写好前端,先练好内功. 栈内存与堆内存 .浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScri ...
- 数据结构与算法JavaScript (一) 栈
序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...
- 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL
树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构. a.树是n ...
- PHP 程序员学数据结构与算法之《栈》
“要成高手,必练此功”. 要成为优秀的程序员,数据结构和算法是必修的内容.而现在的Web程序员使用传统算法和数据结构都比较少,因为很多算法都是包装好的,不用我们去操心具体的实现细节,如PHP的取栈 ...
- 数据结构与算法系列——排序(4)_Shell希尔排序
1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...
随机推荐
- liunx tar 详解
tar [-cxtzjvfpPN] 文件与目录 .... 参数说明 -c: 建立一个压缩文件的指令参数 (crate的缩写): -x:解开一个压缩文件的参数指令: -t:查看tarfile里面的文件 ...
- 工作中oracle常用操作
常用数据库操作 启动数据库监听器lsnrctl start 停止数据库监听器lsnrctl stop 登录oraclesqlplus / as sysdba启动oralcestartup;关闭orac ...
- HomeLede 2020.5.27更新 UPnP+NAS+多拨+网盘+DNS优化+帕斯沃/Clash 无缝集成+软件包
交流群:QQ 1030484865 电报 t.me/t_homelede 固件说明 基于Lede OpenWrt R2020.5.20版本(源码截止2020.5.27)及若干自行维护的软件包 结合 ...
- Rocket - tilelink - RAMModel
https://mp.weixin.qq.com/s/9ccDTm6HytvfGN5R2CPoAQ 简单介绍RAMModel的实现. 1. 基本介绍 RAMModel用于定义内存 ...
- SpringBoot学习笔记(十五:OAuth2 )
@ 目录 一.OAuth 简介 1.什么是OAuth 2.OAuth 角色 3.OAuth 授权流程 4.OAuth授权模式 4.1.授权码 4.2.隐藏式 4.3.密码式 4.4.凭证式 二.实践 ...
- Java实现 LeetCode 630 课程表 III(大小堆)
630. 课程表 III 这里有 n 门不同的在线课程,他们按从 1 到 n 编号.每一门课程有一定的持续上课时间(课程时间)t 以及关闭时间第 d 天.一门课要持续学习 t 天直到第 d 天时要完成 ...
- Java实现 蓝桥杯 基础练习 字母图形
基础练习 字母图形 时间限制:1.0s 内存限制:256.0MB 提交此题 锦囊1 锦囊2 问题描述 利用字母可以组成一些美丽的图形,下面给出了一个例子: ABCDEFG BABCDEF CBABCD ...
- Java实现 蓝桥杯 算法训练 约数个数
算法提高 约数个数 时间限制:1.0s 内存限制:512.0MB 输入一个正整数N (1 样例输入 12 样例输出 6 样例说明 12的约数包括:1,2,3,4,6,12.共6个 import jav ...
- Java实现 LeetCode 377 组合总和 Ⅳ
377. 组合总和 Ⅳ 给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数. 示例: nums = [1, 2, 3] target = 4 所有可能的组合为: (1, 1 ...
- java实现第三届蓝桥杯填算式
** 填算式** [结果填空] (满分11分) 看这个算式: ☆☆☆ + ☆☆☆ = ☆☆☆ 如果每个五角星代表 1 ~ 9 的不同的数字. 这个算式有多少种可能的正确填写方法? 173 + 286 ...