动机
举例子:字符串匹配
应用 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);
}
}
要点