小马

现在是零将来是无限

导航

用 Interpreter 模式设计算24的程序

这两天学习设计模式,弄了一个算24的程序。

程序是这样的:任意给出4个1-10的数,加上+ - * / 四个运算符中选择三个进行排列组合。
按照逆波兰表达式 用 Interpreter 模式解析这个字符串序列,并且计算结果,如果等于24就打印出表达式。

其中排列组合采用了微软网站上的代码,其他部分都是原创。

这里提供c#项目源代码供大家参考

上下文类:
 public class Context
    
{
        
// Fields
        private string input;

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


        
// Properties
        public string Input
        
{
            
get return input; }
            
set { input = value; }
        }


        
public bool IsValid
        
{
            
get
            
{
                
string tmp = input;
                
string operators = "+-*/";

                
int last;
                
while ( (last = tmp.LastIndexOfAny(operators.ToCharArray())) != -1 && tmp != "")
                
{
                    
if (last + 2 > tmp.Length - 1)
                        
break;

                    tmp 
= tmp.Remove(last, 3);

                    
if (tmp == "")
                        
return true;

                    tmp 
= tmp.Insert(last, "0");
                }


                
if (tmp == "")
                    
return true;
                
else
                    
return false;
            }

        }


        
public bool Skip(string token)
        
{
            
if (input.StartsWith(token))
                input 
= input.Substring(token.Length);
            
else
                
return false;

            
return true;
        }


        
public Expression GetExpression()
        
{
            
if (input.StartsWith("+"))
                
return new PlusExpression();
            
else if (input.StartsWith("-"))
                
return new MinusExpression();
            
else if (input.StartsWith("*"))
                
return new MultiplyExpression();
            
else if (input.StartsWith("/"))
                
return new DivideExpression();
            
else
                
return new LiteralExpression();
        }


        
public string GetNumber()
        
{
            
return input.Substring(01);
        }


        
public bool HasMoreInput
        
{
            
get return this.input.Length > 0; }
        }


        
public override bool Equals(object obj)
        
{
            
if (obj as Context == null)
                
return false;

            
if ((obj as Context).Input.Equals(this.Input))
                
return true;
            
else
                
return false;
        }


        
public override int GetHashCode()
        
{
            
return this.input.GetHashCode();
        }

    }

表达式接口

    public interface Expression
    
{
        
bool Interpret(Context context);

        
decimal Caculate();

        
bool CanCaculate get;}

        
bool IsValid get;}
    }

以下是加减乘除表达式的实现:
    public class PlusExpression:Expression
    
{
        Expression addend;
        Expression augend;

        
public PlusExpression()
        
{
        }


        
#region Properties
        
public Expression Addend
        
{
            
get
            
{
                
return addend;
            }


            
set
            
{
                addend 
= value;
            }

        }


        
public Expression Augend
        
{
            
get
            
{
                
return augend;
            }


            
set
            
{
                augend 
= value;
            }

        }
 
        
#endregion


        
#region Expression Members

        
public bool Interpret(Context context)
        
{
            
if (!context.Skip("+"))
                
return false;

            
this.augend = context.GetExpression();

            
if (!augend.Interpret(context))
                
return false;

            
this.addend = context.GetExpression();

            
return addend.Interpret(context);
        }


        
public bool CanCaculate
        
{
            
get
            
{
                
return this.augend.CanCaculate &&
              
this.addend.CanCaculate;
            }

        }


        
public decimal Caculate()
        
{
            
return this.augend.Caculate() +
                
this.addend.Caculate();
        }


        
public bool IsValid
        
{
            
get return this.augend != null && this.addend != null; }
        }


        
#endregion


        
#region Overrided Object Methods
        
public override bool Equals(object obj)
        
{
            
if (obj as PlusExpression == null)
                
return false;

            
if ((obj as Expression).IsValid &&
                ((obj 
as PlusExpression).Augend.Equals(this.Augend)
                    
&& (obj as PlusExpression).Addend.Equals(this.Addend)
                
||
                  (obj 
as PlusExpression).Augend.Equals(this.Addend)
                    
&& (obj as PlusExpression).Addend.Equals(this.Augend)
                ))
                
return true;

            
return false;
        }


        
public override int GetHashCode()
        
{
            
if (!this.IsValid)
                
return 0;

            
return augend.GetHashCode() +
                
this.addend.GetHashCode();
        }


        
public override string ToString()
        
{
            
return String.Format("({0} + {1})"this.augend, this.addend);
        }
 
        
#endregion

    }


public class MinusExpression : Expression
    
{
        Expression minuend;
        Expression subtrahend;

        
public MinusExpression()
        
{
        }


        
#region Properties
        
public Expression Subtrahend
        
{
            
get
            
{
                
return subtrahend;
            }


            
set
            
{
                subtrahend 
= value;
            }

        }


        
public Expression Minuend
        
{
            
get
            
{
                
return minuend;
            }


            
set
            
{
                minuend 
= value;
            }

        }
 
        
#endregion


        
#region Expression Members

        
public bool Interpret(Context context)
        
{
            
if (!context.Skip("-"))
                
return false;

            
this.subtrahend = context.GetExpression();

            
if (!subtrahend.Interpret(context))
                
return false;

            
this.minuend = context.GetExpression();

            
return minuend.Interpret(context);
        }


        
public decimal Caculate()
        
{
            
return this.subtrahend.Caculate() -
                
this.minuend.Caculate();
        }


        
public bool IsValid
        
{
            
get return this.minuend != null && this.subtrahend != null; }
        }


        
public bool CanCaculate
        
{
            
get return this.subtrahend.CanCaculate &&
                
this.minuend.CanCaculate; }

        }


        
#endregion


        
#region Overrided Object Methods
        
public override string ToString()
        
{
            
return String.Format("({0} - {1})"this.subtrahend, this.minuend);
        }


        
public override bool Equals(object obj)
        
{
            
if (obj as MinusExpression == null)
                
return false;

            
if ((obj as Expression).IsValid &&
                (obj 
as MinusExpression).Subtrahend.Equals(this.Subtrahend)
                
&& (obj as MinusExpression).Minuend.Equals(this.Minuend))
                
return true;

            
return false;
        }


        
public override int GetHashCode()
        
{
            
if (!this.IsValid)
                
return 0;
            
return this.Subtrahend.GetHashCode() + this.Minuend.GetHashCode();
        }
 
       
#endregion

    }


 
public class MultiplyExpression:Expression
    
{
        Expression multiplicand;
        Expression multiplier;

        
public MultiplyExpression()
        
{
        }


        
#region Properties
        
public Expression Multiplicand
        
{
            
get
            
{
                
return multiplicand;
            }


            
set
            
{
                multiplicand 
= value;
            }

        }



        
public Expression Multiplier
        
{
            
get
            
{
                
return multiplier;
            }


            
set
            
{
                multiplier 
= value;
            }

        }
 
        
#endregion


        
#region Expression Members

        
public bool Interpret(Context context)
        
{
            
if (!context.Skip("*"))
                
return false;

            
this.multiplicand = context.GetExpression();

            
if (!multiplicand.Interpret(context))
                
return false;

            
this.multiplier = context.GetExpression();

            
return multiplier.Interpret(context);
        }


        
public bool CanCaculate
        
{
            
get
            
{
                
return this.multiplicand.CanCaculate &&
              
this.multiplier.CanCaculate;
            }

        }


        
public decimal Caculate()
        
{
            
return this.multiplicand.Caculate() *
                
this.multiplier.Caculate();
        }


        
public bool IsValid
        
{
            
get return this.multiplicand != null && this.multiplier != null; }
        }


        
#endregion


        
#region Overrided Object Methods
        
public override string ToString()
        
{
            
return String.Format("({0} * {1})"this.multiplicand, this.multiplier);
        }


        
public override bool Equals(object obj)
        
{
            
if (obj as MultiplyExpression == null)
                
return false;

            
if ((obj as Expression).IsValid &&
                ((obj 
as MultiplyExpression).Multiplicand.Equals(this.Multiplicand)
                    
&& (obj as MultiplyExpression).Multiplier.Equals(this.Multiplier)
                
||
                  (obj 
as MultiplyExpression).Multiplicand.Equals(this.Multiplier)
                    
&& (obj as MultiplyExpression).Multiplier.Equals(this.Multiplicand)
                ))
                
return true;

            
return false;
        }


        
public override int GetHashCode()
        
{
            
if (!this.IsValid)
                
return 0;
            
return multiplicand.GetHashCode() +
                
this.multiplier.GetHashCode();
        }
 
        
#endregion

    }


 
public class DivideExpression:Expression
    
{
        Expression dividend;
        Expression divisor;

        
public DivideExpression()
        
{
        }


        
#region Properties
        
public Expression Dividend
        
{
            
get
            
{
                
return dividend;
            }


            
set
            
{
                dividend 
= value;
            }

        }


        
public Expression Divisor
        
{
            
get
            
{
                
return divisor;
            }


            
set
            
{
                divisor 
= value;
            }

        }


        
#endregion

        
        
#region Expression Members

        
public bool Interpret(Context context)
        
{
            
if (!context.Skip("/"))
                
return false;

            
this.dividend = context.GetExpression();

            
if (!dividend.Interpret(context))
                
return false;

            
this.divisor = context.GetExpression();

            
return divisor.Interpret(context);
        }
       

        
public bool CanCaculate
        
{
            
get return this.dividend.CanCaculate &&
                
this.divisor.CanCaculate && 
                
this.divisor.Caculate() != 0; }

        }


        
public decimal Caculate()
        
{
            
return this.dividend.Caculate() / this.divisor.Caculate();
        }


        
public bool IsValid
        
{
            
get return this.dividend != null && this.divisor != null; }
        }


        
#endregion


        
#region Overrided Object Methods
        
public override string ToString()
        
{
            
return String.Format("({0} / {1})"this.dividend, this.divisor);
        }


        
public override bool Equals(object obj)
        
{
            
if (obj as DivideExpression == null)
                
return false;

            
if ((obj as Expression).IsValid &&
                (obj 
as DivideExpression).Dividend.Equals(this.Dividend)
                
&& (obj as DivideExpression).Divisor.Equals(this.Divisor))
                
return true;

            
return false;
        }


        
public override int GetHashCode()
        
{
            
if (!this.IsValid)
                
return 0;
            
return this.Dividend.GetHashCode() + this.Divisor.GetHashCode();
        }


        
#endregion

    }

posted on 2005-05-04 11:20  mahope  阅读(1826)  评论(4编辑  收藏  举报