Interpreter(解释器模式——行为模型)

动机在这里插入图片描述
举例子:字符串匹配
应用 Email检测、身份证号匹配、QQ号匹配等等。每一种匹配都需要特定算法来计算。
但这些问题模式相似,但变化剧烈。

意图
在这里插入图片描述
结构:
在这里插入图片描述
代码:
将文字转化为数字
Context

public class Context
{
    private string statement;//存储字符串,直到变空结束
    private int data;//存储每次计算的值

    public Context(string statement)
    {
        this.statement = statement;
    }

    public string Statement
    {
        get
        {
            return statement;
        }
        set
        {
            statement = value;
        }
    }

    public int Data
    {
        get
        {
            return data;
        }
        set
        {
            data = value;
        }
    }
}

AbstractExpression

public abstract class Expression
{
    protected Dictionary<string, int> table = new Dictionary<string, int>(9);

    public Expression()
    {
        //不变的映射表
        table.Add("一",1);
        table.Add("二",2);
        table.Add("三",3);
        table.Add("四",4);
        table.Add("五",5);
        table.Add("六",6);
        table.Add("七",7);
        table.Add("八",8);
        table.Add("九",9);
    }

    public virtual void Interpret(Context context)
    {
        if (context.Statement.Length == 0)
        {
            return;
        }

        foreach (string key in table.Keys)
        {
            int value = table[key];
            if (context.Statement.EndsWith(key + GetPostfix()))//获取字符串中一部分,就是上面注释的一个括号
            {
                context.Data += value * this.Multiplier();//this.Multiplier(),表示数量级(个十百千)
                context.Statement = context.Statement.Substring(0, context.Statement.Length-this.GetLength());
                //在statement中删去加完的部分
            }

            if (context.Statement.EndsWith("零"))//有些表示如“四千零五”,该句解决其中的“零”
            {
                context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
            }
        }
    }

    public abstract string GetPostfix();
    public abstract int Multiplier();

    public virtual int GetLength()
    {
        return this.GetPostfix().Length + 1;
    }
}

TerminalExpression

public class GeExpression : Expression
{
    public override string GetPostfix()//后缀
    {
        return "";
    }

    public override int Multiplier()
    {
        return 1;
    }

    public override int GetLength()
    {
        return 1;
    }
}

public class ShiExpression : Expression
{
    public override string GetPostfix()
    {
        return "十";
    }

    public override int Multiplier()
    {
        return 10;
    }
}

public class BaiExpression : Expression
{
    public override string GetPostfix()
    {
        return "百";
    }

    public override int Multiplier()
    {
        return 100;
    }
}
public class QianExpression : Expression
{
    public override string GetPostfix()
    {
        return "千";
    }

    public override int Multiplier()
    {
        return 1000;
    }
}

//对于万,有可能【(四百七十一)(万)】
public class WanExpression : Expression
{
    public override string GetPostfix()
    {
        return "万";
    }
    
    public override int Multiplier()
    {
        return 10000;
    }

    public override void Interpret(Context context)
    {
        if (context.Statement.Length == 0)
            return;
        ArrayList tree = new ArrayList();
        tree.Add(new GeExpression());
        tree.Add(new ShiExpression());
        tree.Add(new BaiExpression());
        tree.Add(new QianExpression());

        foreach (string key in table.Keys)
        {
            if (context.Statement.EndsWith(GetPostfix()))
            {
                int temp = context.Data;//保存之前的数据
                context.Data = 0;
                context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
                //计算万括号里的东西,上面先把万刨除
                //下面对上面例子,开始计算(四百七十一)
                foreach (Expression exp in tree)
                {
                    exp.Interpret(context);
                }

                context.Data = temp + this.Multiplier() * context.Data;
            }
        }   
    }
}

使用

internal class Program
{
    public static void Main(string[] args)
    {
        string roman = "五千三百零九万四千零五十二";//计算方法   (四百)(五十)(二),从右向左计算

        Context context = new Context(roman);

        ArrayList tree = new ArrayList();//顺序,从右到左,从个位到十位
        tree.Add(new GeExpression());
        tree.Add(new ShiExpression());
        tree.Add(new BaiExpression());
        tree.Add(new QianExpression());
        tree.Add(new WanExpression());

        foreach (Expression exp in tree)
        {
            exp.Interpret(context);
        }
        
        Console.WriteLine("{0}={1}",roman,context.Data);

    }
}

要点
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值