首页 > Code, 设计模式 > 初尝Interpretor 模式

初尝Interpretor 模式

这个模式,一般用的很少。通常一个解释器,都会有专门的对象或者更底层(更高效)的工具来解决相应的问题。但有通常,就会有特殊的情况。当我们需要剖析某个具有结构性的对象,而这个对象并没有那么庞大时,就可以采用Interpretor 模式。

意图:
给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。

结构图:

Interpretor 模式结构

这个模式让我纠结了几天。原因不在理解这个模式本身,而是老师在课堂举的一个解释器的例子(将汉语数字转换成阿拉伯数字。比如:九千一百二十万六千三百二十一 –>91206321 )这样的计算处理,不用设计模式,也能实现。但,使用了设计模式,可以在代码复用以及一些小型的语法处理问题得到很好的效果。当然最后还是实现了,但这充分说明,自己实现一个解释器,并不容易。

在写代码的过程中,我有尝试从最高位向低位来转换,但发现后期扩展就受到了这个方向的限制。所以,我得出了一个不完全的总结,就是在使用Interpretor 模式的过程中,应该先从最小的单位单元(个位)进行,然后依次递增。

代码

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

namespace DesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化翻译数据...
            string[] numbers = { "九千一百二十万",
                                   "九千一百二十万六千三百二十一",
                                   "六千",
                                   "六千零一",
                                   "六千零一十",
                                   "六千一",
                                   "六千一百",
                                   "六千二百一十",
                                   "六千二百一",
                                   "六千二百零一",
                                   "六千零二十一",
                                   "六千三百二十一",
                                   "一百",
                                   "一百一",
                                   "一百一十",
                                   "一百零一",
                                   "一百一十一",
                                   "二十一",
                                   "二十",
                                   "八" };
            ArrayList contextList = new ArrayList();
            for (int i = 0; i < numbers.Length; i++)
            {
                contextList.Add(new Context(numbers[i]));
            }
            //初始化编译器...
            OneExpression one = new OneExpression();
            TenExpression ten = new TenExpression();
            HundredExpression hun = new HundredExpression();
            ThousandExpression thou = new ThousandExpression();
            TenThousandExpression tenThou = new TenThousandExpression();

            ArrayList list = new ArrayList();
            list.Add(one);
            list.Add(ten);
            list.Add(hun);
            list.Add(thou);
            list.Add(tenThou);

            //开始翻译工作啦...
            foreach (Context c in contextList)
            {
                Console.Write("Input: {0}\t", c.Input);
                foreach (Expression ex in list)
                    ex.Interprete(c);
                Console.WriteLine("Output: {0}", c.Output);

            }

        }
    }
    class Context {
        private string _input;

        public string Input
        {
            get { return _input; }
            set { _input = value; }
        }
        private long _output;

        public long Output
        {
            get { return _output; }
            set { _output = value; }
        }

        public Context(string input) {
            this._input = input;
        }
    }

    abstract class Expression
    {
        protected Dictionary charDic = new Dictionary();
        protected Stack mutiplier = new Stack();
        protected int _data;
        public Expression()
        {
            charDic.Add("一", 1);
            charDic.Add("二", 2); charDic.Add("两", 2);
            charDic.Add("三", 3); charDic.Add("四", 4);
            charDic.Add("五", 5); charDic.Add("六", 6);
            charDic.Add("七", 7); charDic.Add("八", 8);
            charDic.Add("九", 9);
        }
        public abstract void Interprete(Context context);
    }

    class OneExpression : Expression
    {
        public override void Interprete(Context context)
        {
            //throw new NotImplementedException();
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (charDic.ContainsKey(context.Input))
                {
                    this._data = charDic[context.Input];
                    context.Output += this._data;
                    context.Input = String.Empty;
                    return;
                }
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (charDic.ContainsKey(lastWord))
                {
                    this._data = charDic[lastWord];
                    context.Output += this._data;
                    context.Input = context.Input.Substring(0, context.Input.Length - 1);
                }
            }
            if (context.Input.Length > 2)
            {
                if (charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("十") || preWord.EndsWith("零"))
                    {
                        this._data = charDic[lastWord];
                        context.Output += this._data;
                        context.Input = context.Input.Substring(0, context.Input.Length - 2);
                    }
                }
            }
        }
    }
    class TenExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    context.Output += charDic[context.Input] * 10;
                }
                if (context.Input.Equals("十"))
                {
                    context.Output += 10;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("十"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 10;
                        context.Input = String.Empty;
                    }
                }
            }

            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("十"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("百") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 10;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class HundredExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length == 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    this._data = this.charDic[context.Input];
                    context.Output += this._data * 100;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("百"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 100;
                        context.Input = String.Empty;
                    }
                }
            }
            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("百"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("千") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 100;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class ThousandExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.Length == 1)
            {
                if (this.charDic.ContainsKey(context.Input))
                {
                    this._data = this.charDic[context.Input];
                    context.Output += this._data * 1000;
                }
                context.Input = String.Empty;
                return;
            }
            string lastWord = context.Input.Substring(context.Input.Length - 1);
            string preWord = context.Input.Substring(0, context.Input.Length - 1);
            if (context.Input.Length == 2)
            {
                if (lastWord.Equals("千"))
                {
                    if (this.charDic.ContainsKey(preWord))
                    {
                        context.Output += this.charDic[preWord] * 1000;
                        context.Input = String.Empty;
                    }
                }
            }
            if (context.Input.Length > 2)
            {
                if (lastWord.Equals("千"))
                {
                    lastWord = preWord.Substring(preWord.Length - 1);
                    preWord = preWord.Substring(0, preWord.Length - 1);
                }
                if (this.charDic.ContainsKey(lastWord))
                {
                    if (preWord.EndsWith("万") || preWord.EndsWith("零"))
                    {
                        this._data = this.charDic[lastWord];
                        context.Output += this._data * 1000;
                        context.Input = preWord.Substring(0, preWord.Length - 1);
                    }
                }
            }
        }
    }
    class TenThousandExpression : Expression
    {
        public override void Interprete(Context context)
        {
            if (context.Input.Length <= 0) return;
            if (context.Input.EndsWith("万"))
            {
                context.Input = context.Input.Substring(0, context.Input.Length - 1);
            }
            long temp = context.Output;
            context.Output = 0;
            OneExpression one = new OneExpression();
            TenExpression ten = new TenExpression();
            HundredExpression hun = new HundredExpression();
            ThousandExpression thou = new ThousandExpression();
            ArrayList list = new ArrayList();
            list.Add(one);
            list.Add(ten);
            list.Add(hun);
            list.Add(thou);
            foreach (Expression ex in list)
            {
                ex.Interprete(context);
            }
            context.Output *= 10000;
            context.Output += temp;

        }
    }
}

运行结果

Interpretor 运行结果

这里是测试程序,如果有bug,请联系我哟。点击下载:Interpretor 演示代码 (36)

  1. 本文目前尚无任何评论.
  1. 2010年5月9日19:40 | #1