栈通常用于解析某种类型的文本串。通常,文本串是用于计算机语言写的代码行,而解析它们的程序就是编译器。
为了解释清楚,下面看一个检查用户输入的一行文本中分隔符的程序。文本不一定是实际的C#代码(也可以是)。但它需要使用和C#同样的分隔符。分隔符包括大括号'{' 和 '}', 中括号 ‘[’ 和 ']', 和小括号‘(’ 和 ‘)’。每个左分隔符需要和右分隔符匹配;这就是说,每个 ‘{’ 后面要有‘}’来匹配,以此类推。同事,在字符串中后出现的左分隔符应该比早出现的左分隔符先完成匹配。下面是一些例子:
c[d]// correct
a{b[c]d}e// correct
a{b(c]d}e// not correct; ] doesn't match (
a[b{c}d]e}// not correct; nothing matches final }
a{b(c)// not correct; nothing matches opening {
看看对下面这个正确的字符串,栈的变化过程:
a{b(c[d]e)f}
分隔符匹配中栈的数据项
----------------------------------------------------------------------------------------------
所读字符 栈中内容
----------------------------------------------------------------------------------------------
a
{ {
b {
( {(
c {(
[ {([
d {([
] {(
e {(
) {
f {
}
这个方法的可行性在于, 最后出现的左边分隔符需要最先匹配。这个规律符合栈的后进先出的特点。
程序代码如下。用BracketChecker类中check()方法完成解析。
StackX类,定义一个栈类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Brackets
{
class StackX
{
private int maxSize;
private char[] stackArray;
private int top;
public StackX(int s)
{
maxSize = s;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j)
{
if (isFull())
Console.Write("Stack is full");
stackArray[++top] = j;
}
public char pop()
{
if (isEmpty())
Console.Write("Stack is Empty");
return stackArray[top--];
}
public char peek()
{
return stackArray[top];
}
public bool isEmpty()
{
return (top == -1);
}
public bool isFull()
{
return (top == maxSize - 1);
}
}
}
BracketChecker类,解析字符串。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Brackets
{
class BracketChecker
{
private string input;
public BracketChecker(string inStr)
{
input = inStr;
}
public void check()
{
int stackSize = input.Length;
StackX theStack = new StackX(stackSize);
int flag = 0; //不匹配的分隔符个数
int charNum = 0; //记录压入栈中的分隔符个数
char[] ch = input.ToCharArray();
for (int i = 0; i < input.Length; i++)
{
char c = ch[i];
switch (c)
{
case '{':
case '[':
case '(':
theStack.push(c);
charNum++;
break;
case '}':
case ']':
case ')':
if (!theStack.isEmpty())
{
char chx = theStack.pop();
if ((c == '}' && chx != '{') ||
(c == ']' && chx != '[') ||
(c == ')' && chx != '(') )
{
Console.WriteLine("Error: " + c + " at " + i);
flag++;
}
else
{
charNum--; //成功匹配分隔符,就递减栈中分隔符个数
}
}
else
{
Console.WriteLine("Error: " + c + " at " + i);
flag++;
}
break;
default:
break;
}
}
if (charNum == 0 && flag == 0)
{
Console.WriteLine("-------------Correct!!!");
}
else
{
Console.WriteLine("Error: missing right delimiter");
}
}
}
}
BracketsApp类,主程序。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Brackets
{
/// <summary>
/// 分隔符匹配 a{b[c(d)e]f}
/// </summary>
class BracketsApp
{
static void Main(string[] args)
{
string input;
while (true)
{
input = Console.ReadLine();
if (input.Equals(""))
break;
BracketChecker theChecker = new BracketChecker(input);
theChecker.check();
}
}
}
}
Result: