2009年11月3日星期二

Interpreter 设计模式

Interpreter 解释器,如同普通的Basic语言等的解释器一样,一边读入语言(字符串),一边解释执行。Interpreter 设计模式就是用来解决这种需要边读入边解释程序的设计模式。
罗马数字的表示规则如下:

罗马数字共有7个,即Ⅰ(1),Ⅴ(5),Ⅹ(10),Ⅼ(50),Ⅽ(100),Ⅾ(500),Ⅿ(1000)。按照下述的规则可以表示任意正整数。*需要注意的是罗马数字中没有“0”。

重复数次:1个罗马数字重复几次,就表示这个数的几倍。
右加左减:
在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。
在一个较大的罗马数字的左边记上一个较小的罗马数字,表示大数字减小数字。
但是,左减不能跨越一个位数。比如,99不可以用ⅠⅭ表示,而是用ⅩⅭⅠⅩ表示。(等同于阿拉伯数字每位数字分别表示)
例如:999 = 900+90+9 = ⅭⅯ+ⅩⅭ+ⅠⅩ = ⅭⅯⅩⅭⅠⅩ
此外,左减数字不能超过1位,比如8写成ⅤⅠⅠⅠ,而非ⅠⅠⅩ。
同理,右加数字不能超过3位,比如14写成ⅩⅠⅤ,而非ⅩⅠⅠⅠⅠ。
加线乘千:在1个罗马数字的上方加上1条横线或者在右下方写Ⅿ,表示将这个数乘以1000,即是原数的1000倍。
同理,如果上方有2条横线,即是原数的1000000倍。
例外:由于ⅠⅤ是古罗马神话主神朱庇特(IVPITER,古罗马字母没有J和U)的首字,因此有时用ⅠⅠⅠⅠ代替ⅠⅤ。
[编辑] 示例
Ⅰ - 1 unus
ⅠⅠ - 2 duo
ⅠⅠⅠ - 3 tres
ⅠⅤ - 4 quattuor
Ⅴ - 5 quinque
ⅤⅠ - 6 sex
ⅤⅠⅠ - 7 septem
Ⅾ - 500
ⅮⅤⅠ - 506
ⅮⅬⅤ - 555
ⅮⅭⅬⅩⅤⅠ - 666
ⅮⅭⅭⅬⅩⅩⅤⅠⅠ - 777
ⅮⅭⅭⅭⅬⅩⅩⅩⅤⅠⅠⅠ - 888
Ⅿ - 1,000
ⅯⅭ - 1,100
ⅯⅭⅭ - 1,200
ⅯⅭⅭⅭ - 1,300

用解释器模式实现的将罗马字符串转化为数值的程序如下:

class MainApp
{
///

/// Interpreter设计模式,将罗马字符串转化成数值。
static void Main()
{
string roman = "MCMLXXX";
Context context = new Context(roman);
// Build the 'parse tree'

List tree = new List();
tree.Add(new ThousandExpression());
tree.Add(new HundredExpression());
tree.Add(new TenExpression());
tree.Add(new OneExpression());
// Interpret
foreach (Expression exp in tree)
{
exp.Interpret(context);
}
Console.WriteLine("{0} = {1}", roman, context.Output);
// Wait for user
Console.ReadKey();
}
}
//内容类,要解释的对象类。
class Context
{
private string _input;
private int _output;
//构造函数,用字符串(要解释的语言)初始化。
public Context(string input)
{
this._input = input;
}
// 取得或者设置输入值
public string Input
{
get { return _input; }
set { _input = value; }
}
// 取得或者设置输出值
public int Output
{
get { return _output; }
set { _output = value; }
}
}
//抽象的表达式类,对表达式进行解释
abstract class Expression
{
//对context的内容进行解释。
public void Interpret(Context context)
{
if (context.Input.Length == 0)
return;
if (context.Input.StartsWith(Nine()))
{
context.Output += (9 * Multiplier());
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(Four()))
{
context.Output += (4 * Multiplier());
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(Five()))
{
context.Output += (5 * Multiplier());
context.Input = context.Input.Substring(1);
}
while (context.Input.StartsWith(One()))
{
context.Output += (1 * Multiplier());
context.Input = context.Input.Substring(1);
}
}
//抽象函数,在具体类中重新
public abstract string One();
public abstract string Four();
public abstract string Five();
public abstract string Nine();
public abstract int Multiplier();

}
//终结符表达式类,用来检查罗马数字:M
class ThousandExpression : Expression
{
public override string One() { return "M"; }
public override string Four() { return " "; }
public override string Five() { return " "; }
public override string Nine() { return " "; }
public override int Multiplier() { return 1000; }
}
//终结符表达式类,用来检查罗马数字:C, CD, D or CM
class HundredExpression : Expression
{
public override string One() { return "C"; }
public override string Four() { return "CD"; }
public override string Five() { return "D"; }
public override string Nine() { return "CM"; }
public override int Multiplier() { return 100; }
}
//终结符表达式类,用来检查罗马数字:X, XL, L and XC
class TenExpression : Expression
{
public override string One() { return "X"; }
public override string Four() { return "XL"; }
public override string Five() { return "L"; }
public override string Nine() { return "XC"; }
public override int Multiplier() { return 10; }
}

//终结符表达式类,用来检查罗马数字:I, II, III, IV, V, VI, VI, VII, VIII, IX
class OneExpression : Expression
{
public override string One() { return "I"; }
public override string Four() { return "IV"; }
public override string Five() { return "V"; }
public override string Nine() { return "IX"; }
public override int Multiplier() { return 1; }

}

执行结果:
MCMLXXX= 1980

没有评论:

发表评论