首页 > 代码库 > 四则运算

四则运算

家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习。于是,自己在业余时间开发了一个四则运算算式生成器,名为:CalculateIt2。项目是开源的,源码地址是:https://github.com/daxnet/CalculateIt2。也可以在标准的.NET Framework 4.6.1的项目中,通过nuget来引用这个类库,nuget ID是:CalculateIt2.Engine。为什么名字后面有一个“2”呢?不是说这个项目比较二,而是之前做过一个简单的版本,但是功能太差,就被抛弃了。现在是第二个版本。

先睹为快

首先,打开Visual Studio 2015,新建一个.NET Framework 4.6.1的控制台应用程序,在项目上点击鼠标右键,选择Manage NuGet Packages,打开包管理界面,在搜索栏中输入CalculateIt2.Engine,此时就可以将本类库添加到项目中:

技术分享

在Program.cs中,输入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Program
{
    static void Main(string[] args)
    {
        var formation = "{10}+-*/|3";
        var equation = new ArithmeticEquationGenerator(formation,
            new AvoidNegativeResultRule(),
            new DivisibilityEnsuranceRule());
        for (var i = 0; i < 10; i++)
        {
            var calculation = equation.Generate();
            Console.WriteLine($"{calculation.ToFormattedString(SpacingOption.Thin)} = {calculation.Value}");
        }
    }
}

以上代码会产生10个10以内,包含3个计算因子的四则混合运算算式,如下:

技术分享

基本功能

此算式生成器类库(CalculateIt2.Engine)不仅可以根据指定的算式格式产生算式,而且还能自定义算式生成规则,并使用生成的算式产生各种不同的试题题型。

算式格式定义

在ArithmeticEquationGenerator类的构造函数中,第一个参数指定了需要生成的算式格式,例如,在上例的格式字符串{10}+-*/|3中:

  • {10}:指定了每个因子的取值范围,语义上表示10以内。{30}则表示30以内
  • +-*/:指定了算式中可以包含的运算符,这里是支持四则运算。如果只指定+-,那么生成的算式中只会出现加法和减法。至少需要指定一个运算符,相同的运算符不能出现多次
  • |:竖线是前半部分和后半部分的分割线。竖线及以后的部分都是可有可无的
  • 竖线之后的3:表示产生3个因子的算式,比如上例中所有的算式都是由三个因子组成。此处还可以指定因子个数的范围,最大数和最小数之间用减号隔开,比如:{10}+-|2-5,则表示需要生成10以内的加减法运算算式,每个算式最多可以包含5个因子,最少需要包含2个因子

算式生成规则

在ArithmeticEquationGenerator类的构造函数的第二个之后的参数中,指定了算式生成规则的类的实例。这些类都实现了CalculateIt2.Engine.Rules.IRule接口,目前在CalculateIt2.Engine类库中提供了以下几种生成规则:

  • AvoidDivideByZeroRule:当算式中出现除法的时候,避免除法运算出现“除以零”的错误。此规则是内建规则,由ArithmeticEquationGenerator产生的算式都适用该规则
  • AvoidNegativeResultRule:当算式中出现减法的时候,避免减法运算出现负数结果。此规则可以在构造ArithmeticEquationGenerator时选择指定,它的选择与否不会对算式的生成产生致命的影响。但如果是为低年级的小朋友生成算式,那么负数的概念就应该去掉(人家一年级还没有接触负数呢)
  • DivisibilityEnsuranceRule:当算式中出现除法的时候,确保被除数可以被除数整除。此规则可以在构造ArithmeticEquationGenerator时选择指定,同样,它的选择与否不会对算式的生成产生致命的影响。对于低年级小朋友,还没有小数的概念,因此,在生成算式的时候,加入这个规则也是很有必要的

除此之外,开发者可以自己扩展IRule接口,定义算式生成的一些特殊规则,比如:在算式中避免出现0这个因子。

多种题型的试题生成

目前支持三种题型的试题生成:标准题,填空题和比大小。不同题型的试题生成器都需要继承于CalculateIt2.Engine.Generation.QuestionGenerator{T}抽象类。目前默认提供了这三种题型的试题生成:

  • RegularQuestionGenerator:生成标准计算题题型,比如:2 + 3 – 1 = __________,同学们把计算结果写在横线上
  • ClozeQuestionGenerator:生成填空题,比如:5 – 3 + (   ) = 6,同学们在括号中填入数字,将算式补全
  • ComparisonQuestionGenerator:比大小题,比如:5 – 1 ○ 2,同学们在圆圈中填入>、<或者=符号

当然,开发者可以根据需要实现更多的题型。一个for循环下来,小朋友们要哭了。

实现

此算式生成器使用了组合模式和经典Visitor模式,并结合动态Visitor模式提供了额外的功能。以下是主要类型的类图(点击查看大图),具体的实现细节就不多介绍了,大家可以参考源代码。

技术分享

应用

我结合DocX这个开源类库,写了一个算术测试试卷的生成软件(就是一个控制台程序),它可以使用CalculateIt2.Engine类库产生10以内加减法的测试试卷,并输出到一个Microsoft Word文档,下面是效果:

技术分享 

请慎重干类似的事情,这样做会让小朋友不喜欢你的。

接下来。。。

这个类库我自己搭建了Jenkins服务器进行持续集成和nuget包的分发,接下来打算介绍一下这方面的内容。

四则运算