您的位置:首页 > 其它

括号匹配算法

2006-09-23 11:09 357 查看
///调用方法
///JFrameWork.DataBase.SQL.MatchString sp = new MatchString();
///sp.ParseStr("(1+8*(9-1)+((1-9)+(2*5)))((z)(z)z(55))((666))(59)", "(", ")");
/////////////////实现代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace JFrameWork.DataBase.SQL
{
/// <summary>
/// 匹配对的结构存储体
/// </summary>
struct MS
{
public int left;
public int right;
public MS(int left, int right)
{
this.left = left;
this.right = right;
}

public MS(MS ms)
{
this.left = ms.left;
this.right = ms.right;
}
}

public class MatchString
{
/// <summary>
/// 左值队列
/// </summary>
List<int> llist = new List<int>();
/// <summary>
/// 右值队列
/// </summary>
List<int> rlist = new List<int>();
/// <summary>
/// 左右值混合队列
/// </summary>
List<int> alllist = new List<int>();
/// <summary>
/// 匹配对存储队列
/// </summary>
List<MS> matchmap = new List<MS>();

public void ParseStr(string str, string lvalue, string rvalue)
{
System.Console.WriteLine("str : {0}", "01234567890123456789012345678901234567890123456789");
System.Console.WriteLine("str : {0}", str);
GetIndex(str, lvalue, rvalue);
SetAllList();
GetNearMatch();
GetRootMatch();
DisplayMatchMap();
}

/// <summary>
/// 得到串的左值以及右值队列序号分别存放在llist以及rlist中
/// </summary>
/// <param name="str"></param>
/// <param name="lvalue"></param>
/// <param name="rvalue"></param>
void GetIndex(string str, string lvalue, string rvalue)
{
int lstartIndex = 0;
int rstartIndex = 0;
bool lb = true;
bool rb = true;
while (lb || rb)
{
if (lb)
{
lstartIndex = str.IndexOf(lvalue, lstartIndex);
if (lstartIndex >= 0)
{
llist.Add(lstartIndex);
System.Console.WriteLine("LValue Index: {0}", lstartIndex);
lstartIndex++;
}
else
{
lb = false;
}
}
if (rb)
{
rstartIndex = str.IndexOf(rvalue, rstartIndex);
if (rstartIndex >= 0)
{
rlist.Add(rstartIndex);
System.Console.WriteLine("RValue Index: {0}", rstartIndex);
rstartIndex++;
}
else
{
rb = false;
}
}
}

}

/// <summary>
/// 设置llist以及rlist中所有的索引序号内容导入到ALLList,并按序号进行排序
/// </summary>
void SetAllList()
{
for (int i = 0; i < llist.Count; i++)
{
alllist.Add(llist[i]);
}
for (int i = 0; i < rlist.Count; i++)
{
alllist.Add(rlist[i]);
}
alllist.Sort();
}

/// <summary>
/// 将alllist中找到最相近的匹配对到matchmap中存储
/// </summary>
void GetNearMatch()
{
Stack<int> stack = new Stack<int>();
for (int i = 0; i < alllist.Count; i++)
{
if (llist.Contains(alllist[i]))
{
stack.Push(alllist[i]);
}
else if (rlist.Contains(alllist[i]))
{
if (stack.Peek() < alllist[i])
{
int tmp = stack.Pop();
matchmap.Add(new MS(tmp, alllist[i]));
System.Console.WriteLine("NeerMatch : {0}\t{1}", tmp, alllist[i]);
}
}
}
}

//本处最终结果尽管是对的 但是我认为这只是一个碰巧得到了正确的结果,而且算法好像也有些问题
//希望有人能解决得到更好的算法
/// <summary>
/// 对matchmap对进行搜索过滤,得到最终的根级匹配对,并返回
/// </summary>
/// <returns></returns>
List<MS> GetRootMatch()
{
List<MS> tmp = new List<MS>();

for (int i = 0; i < matchmap.Count; i++)
{
MS ms = new MS(matchmap[i]);
for (int j = i + 1; j < matchmap.Count; j++)
{
if (matchmap[j].left < matchmap[i].left && matchmap[j].right > matchmap[i].right)
{
ms = new MS(matchmap[j]);
if (!tmp.Contains(ms))
{
tmp.Add(ms);
//System.Console.WriteLine("RootMatch : {0}\t{1}", ms.left, ms.right);
}

xxx:
for (int k = 0; k < matchmap.Count; k++)
{
for (int l = 0; l < tmp.Count; l++)
{
if (matchmap[k].left > tmp[l].left && matchmap[k].right < tmp[l].right)
{
matchmap.RemoveAt(k);
goto xxx;
}
}
}
}

}

}
return matchmap;
}

void DisplayMatchMap()
{
foreach (MS ms in matchmap)
{
System.Console.WriteLine("MatchMap: [L] {0}\t [R] {1}",ms.left, ms.right);
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: