括号匹配算法

///调用方法
///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);
            }
        }


    }
}

posted @ 2006-09-23 11:09  我想去长安  阅读(1626)  评论(1编辑  收藏  举报