栈的特性:后进先出(LIFO)

回文判断

类似123321,123a321即为回文

思路:

  • 将字符串前一半入栈
  • 依次弹出栈与字符串后一半比较
public static bool IsPlalindrome(string str)
{
var stack = new Stack<char>();
for (int i = 0; i < str.Length / 2; i++)
{
stack.Push(str[i]);
} var len = str.Length % 2 == 0 ? str.Length / 2 : (str.Length + 1) / 2;
for (int i = len; i < str.Length; i++)
{
if (stack.Pop() != str[i])
{
return false;
}
}
return true;
}

进制转化

10进制转8进制 1024→2000

转换流程如下:

N N div N mod
1024 128 0
128 16 0
16 2 0
2 0 2

思路:

  • 取模入栈
  • 整除运算直至为0

实现如下:

private static void Main()
{
Console.WriteLine(Get(4396, 8));
Console.ReadKey();
} public static int Get(int value, int i)
{
var stack = new Stack<int>();
while (value != 0)
{
stack.Push(value % i);
value /= i;
}
return int.Parse(string.Join("", stack));
}

括号匹配

  • 圆括号、方括号和花括号可以任意嵌套
  • 正确格式:{{90[]}}(4)
  • 错误格式:{2(1}1)[3]

思路:

  • 如果时(,[,{ 则入栈
  • 如果时),],} 则将对应左边括号弹出栈

实现如下:

private static void Main()
{
Console.WriteLine(Check("{abc[1](2)}sss(aaa)[({})]"));
Console.ReadKey();
} public static bool Check(string str)
{
var stack = new Stack<char>();
foreach (var c in str)
{
switch (c)
{
case '(':
case '{':
case '[':
stack.Push(c);
break;
case ')':
if (stack.Count == 0 || stack.Pop() != '(')
{
return false;
}
else
{
break;
}
case '}':
if (stack.Count == 0 || stack.Pop() != '{')
{
return false;
}
else
{
break;
}
case ']':
if (stack.Count == 0 || stack.Pop() != '[')
{
return false;
}
else
{
break;
}
}
}
return stack.Count == 0;
}

中缀转后缀表达式求职

运算规则

  • 从左算到右
  • 先乘除,后加减
  • 先括号内,后括号外

相邻两个操作符优先级判断如下:

c1表示前一个操作符,c2表示后一个操作符

c1/c2 + - * / ( )
+ > > < < < >
- > > < < < >
* < < > > < >
/ < < > > < >
( < < < < < =
) > > > > >

思路:

  • 分操作数栈和操作符栈
  • 操作数进操作数栈
  • 当前操作符优先级大于顶栈操作符则入栈
  • 当前操作符优先级小于顶栈操作符,则弹出顶栈,弹出两个操作数运算,运算结果再入栈
  • 重复上一步骤,直至将当前操作符入栈
  • 若最后两栈都不为空,则依次弹出操作符与操作数计算,直至操作符栈为空,此时操作数栈剩一个元素即为最终结果。

实现如下:

private static void Main()
{
Console.WriteLine(Calculation("(2+3)*2+2*(6-3)/(4-2)+2"));
Console.ReadKey();
} public static int Calculation(string str)
{
//操作数栈
var opndStack = new Stack<int>();
//操作符栈
var optrStack = new Stack<char>();
foreach (var c in str)
{
if (char.IsDigit(c))
{
//当前的字符是操作数
opndStack.Push(int.Parse(c.ToString()));
}
else
{
//当前的字符是操作符
while (optrStack.Count != 0)
{
var priority = Priority(optrStack.Peek(), c);
if (priority == '<')
{
//栈顶优先级小与当前操作符
//入栈
optrStack.Push(c);
break;
}
if (priority == '=')
{
//栈顶优先级等于当前操作符
//就是左右括号匹配,弹出左括号
optrStack.Pop();
break;
} if (priority != '>')
{
continue;
}
//栈顶优先级大于当前操作符
//需要计算
var optr = optrStack.Pop();
var value2 = opndStack.Pop();
var value1 = opndStack.Pop();
opndStack.Push(Operate(value1, optr, value2));
}
//1.第一次栈为空直接入栈。
//2.退栈直至为空当前操作符也需要入栈,但")"无需入栈
if (optrStack.Count == 0 && c != ')')
{
optrStack.Push(c);
}
}
}
while (optrStack.Count != 0)
{
var optr = optrStack.Pop();
var value2 = opndStack.Pop();
var value1 = opndStack.Pop();
opndStack.Push(Operate(value1, optr, value2));
}
return opndStack.Count == 1 ? opndStack.Pop() : 0;
} public static int Operate(int value1, char optr, int value2)
{
switch (optr)
{
case '+':
return value1 + value2;
case '-':
return value1 - value2;
case '*':
return value1 * value2;
case '/':
return value1 / value2;
}
return 0;
} /// <summary>
/// 比较栈顶操作符与当前操作符优先级
/// </summary>
/// <param name="c1">栈顶操作符</param>
/// <param name="c2">当前操作符</param>
/// <returns></returns>
public static char Priority(char c1, char c2)
{
switch (c1)
{
case '+':
case '-':
if (c2 == '+' || c2 == '-' || c2 == ')')
{
return '>';
}
return '<';
case '*':
case '/':
if (c2 == '(')
{
return '<';
}
return '>';
case '(' when c2 == ')':
return '=';
case '(':
return '<';
case ')':
return '>';
}
return '>';
}

reference

栈的应用

C# 栈的应用的更多相关文章

  1. 通往全栈工程师的捷径 —— react

    腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...

  2. Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)

    --reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...

  3. duang~免费的学习视频来啦:学霸君之全栈测试

    学霸君向童鞋们推荐一款 同名学霸学习 视频教程 重点是完全免费收看学习噢!!! 今天 学霸君推荐腾讯课堂的学霸君之全栈测试 复制下方链接至腾讯课堂中报名学习 https://ke.qq.com/cou ...

  4. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

  5. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  6. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  7. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  8. .NET全栈开发工程师学习路径

    PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...

  9. Nodejs之MEAN栈开发(八)---- 用户认证与会话管理详解

    用户认证与会话管理基本上是每个网站必备的一个功能.在Asp.net下做的比较多,大体的思路都是先根据用户提供的用户名和密码到数据库找到用户信息,然后校验,校验成功之后记住用户的姓名和相关信息,这个信息 ...

  10. 匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置

    0x00 前言: 匹夫在日常和别人交流的时候,常常会发现一旦讨论涉及到“类型”,话题的热度就会立马升温,因为很多似是而非.或者片面的概念常常被人们当做是全面和正确的答案.加之最近在园子看到有人翻译的& ...

随机推荐

  1. java算法(4)---静态内部类实现雪花算法

    静态内部类单例模式实现雪花算法 在生成表主键ID时,我们可以考虑主键自增 或者 UUID,但它们都有很明显的缺点 主键自增:1.自增ID容易被爬虫遍历数据.2.分表分库会有ID冲突. UUID: 1. ...

  2. Go-如何读取yaml,json,ini等配置文件

    1. json使用 JSON 应该比较熟悉,它是一种轻量级的数据交换格式.层次结构简洁清晰 ,易于阅读和编写,同时也易于机器解析和生成. 创建 conf.json: { "enabled&q ...

  3. 建立apk定时自动打包系统第二篇——自动上传文件

    在<建立apk定时自动打包系统第一篇——Ant多渠道打包并指定打包目录和打包日期>这篇文章中介绍多渠道打包的流程.很多时候我们需要将打包好的apk上传到ftp中,这时候我可以修改custo ...

  4. windows和linux下的本机IP的获取(亲测有效)

    package com.handsight.platform.fras.util; import org.apache.log4j.Logger; import javax.servlet.http. ...

  5. PrintWriter out = response.getWriter();乱码解决

     resopnse  request的乱码问题 今天在改项目时,发现这个简单又容易忽视在问题.说起这个问题,比较简单,但也比较容易忽视.下面就具体讲讲这个问什么会出现乱码问题. request乱码指的 ...

  6. Linux环境搭建 | VMware下共享文件夹的实现

    在进行程序开发的过程中,我们经常要在主机与虚拟机之间传递文件,比如说,源代码位于虚拟机,而在主机下阅读或修改源代码,这里就需要使用到 「共享文件」 这个机制了.本文介绍了两种共享文件夹的实现机制:VM ...

  7. 随笔编号-16 MySQL查看表及索引大小方法

    目标:阿里云OS数据库DMS,单个主库最大存储空间为2T.最近公司业务扩展很快,一天数据量达到7.9G左右.要求备份清理历史数据,备份到其他磁盘. 准备: 如果想知道MySQL数据库中每个表占用的空间 ...

  8. unity编辑器扩展_04(使用Selection获取选择的游戏物体)

    代码: [MenuItem("Tools/GetChance", false, 1)]    static void GetChance()    {        if (Sel ...

  9. 数据库回滚(rollback)和撤销(undo)的区别

    数据库回滚(rollback)和撤销(undo)的区别就是把某一个数据库操作恢复到该操作之前的状态,下面结合自己理解总结一下区别,如有错误,欢迎各路大佬斧正: 数据库事务过程:执行SQL——提交   ...

  10. 关于AndroidStudio在真机安装的apk闪退(无法打开)的解决方案

    问题描述: 重新安装AndroidStudio之后 1.发现在真机上安装apk时显示的是应用包名. 2.在真机上安装的apk无法打开,一直闪退. 如图: 解决方案: 关闭AndroidStudio的I ...