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#数据结构与算法系列(九):栈实现综合计算器(中缀表达式)的更多相关文章

  1. javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例

    栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...

  2. 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

    数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...

  3. 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解

    数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...

  4. C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611

    09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...

  5. C#数据结构与算法系列(八):栈(Stack)

    1.介绍 栈是一个先入后出(FILO-First In Last Out)的有序列表 栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的特殊线性表.允许插入和删除的一端,为变化的一端,称为栈顶 ...

  6. JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝

    前言 想写好前端,先练好内功. 栈内存与堆内存 .浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScri ...

  7. 数据结构与算法JavaScript (一) 栈

    序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...

  8. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  9. PHP 程序员学数据结构与算法之《栈》

    “要成高手,必练此功”.   要成为优秀的程序员,数据结构和算法是必修的内容.而现在的Web程序员使用传统算法和数据结构都比较少,因为很多算法都是包装好的,不用我们去操心具体的实现细节,如PHP的取栈 ...

  10. 数据结构与算法系列——排序(4)_Shell希尔排序

    1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...

随机推荐

  1. LinkedList为什么增删快、查询慢

    List家族中共两个常用的对象ArrayList和LinkedList,具有以下基本特征. ArrayList:长于随机访问元素,中间插入和移除元素比较慢,在插入时,必须创建空间并将它的所有引用向前移 ...

  2. Map.Entry的作用

    一般情况下,要输出Map中的key 和 value 是先得到key的集合,然后再迭代(循环)由每个key得到每个value 而Entry可以一次性获得这两个值 Set set = map.keySet ...

  3. S32DS编译程序出现Type region `SRAM' overflowed by 19240 bytes错误

    用S32DS编译工程遇到Type region `SRAM' overflowed by 19240 bytes错误(芯片为S9KEAZ64AMLH) 程序中未初始化的变量存放SRAM中 当程序出现未 ...

  4. [PHP学习教程 - 网络]001.下载/采集远程文件到本地(Download File)

    引言:如何把http://mzitu.com里的图片全部下载下来呢? 一身浩然正气的AC陷入的深思.... 当然这里涉及到的功能有线程,网页请求,页面提取,下载图片等等.今天,我们先讲一下如何下载文件 ...

  5. 学习源码的第八个月,我成了Spring的开源贡献者

    @ 目录 我的经历 碰到的问题 1.担心闹乌龙 2.不知道要怎么提交 3.英文 4.担心问题描述的不清楚 给你的建议 我的经历 关注我的朋友都知道,关注两个字划重点,要考! 我最近一直在写Spring ...

  6. Java实现 LeetCode 832 翻转图像(位运算)

    832. 翻转图像 给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果. 水平翻转图片就是将图片的每一行都进行翻转,即逆序.例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, ...

  7. Java实现 LeetCode 806 写字符串需要的行数 (暴力模拟)

    806. 写字符串需要的行数 我们要把给定的字符串 S 从左到右写到每一行上,每一行的最大宽度为100个单位,如果我们在写某个字母的时候会使这行超过了100 个单位,那么我们应该把这个字母写到下一行. ...

  8. Java实现 LeetCode 216. 组合总和 III(三)

    216. 组合总和 III 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. 解集不能包含重复的组合. ...

  9. Java实现 洛谷 P1103 书本整理

    题目描述 Frank是一个非常喜爱整洁的人.他有一大堆书和一个书架,想要把书放在书架上.书架可以放下所有的书,所以Frank首先将书按高度顺序排列在书架上.但是Frank发现,由于很多书的宽度不同,所 ...

  10. Java实现蓝桥杯正则问题

    题目描述 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...