【android益智游戏源码】【排名互点源码】【相册翻书源码】getdataset源码

时间:2024-11-26 21:21:04 编辑:武汉溯源码燕窝 来源:影视开源源码

1.用C#写简单的Web Service
2.DbUnit (安装 | 使用)
3.求决策树源代码。源码最好使用matlab实现。源码

getdataset源码

用C#写简单的Web Service

       åœ¨å¼€å§‹ä¸‹é¢è¿™ä¸ªä¾‹å­ä¹‹å‰ï¼Œä½ çš„系统需要:

        1、WIN + IIS;

        2、VS.Net;

        3、SQL Server(我这里用的是SQL数据库);

       è¿™ä¸ªWeb Service的例子用的是MS大吹的C#写的,如果你喜欢VB,那么用VB也是一样的哦,只不过语法上一些小的差别而已,道理都是一样的,不过即然MS都鼓吹C#,如果你能够用C#写还是用这为好哦。

       ä¸‹é¢æ˜¯å†™çš„步骤:

       ä¸€ã€æ‰“å¼€VS。NET的集成开发环境,FILE菜单上选择New,新建一个C#的ASP.NET Web Service工程,工程名为WebServiceDemo(完整的是ponents = null;

        /// <summary>

        /// Required method for Designer support - do not modify

        /// the contents of this 源码android益智游戏源码method with the code editor.

        /// </summary>

        private void InitializeComponent()

        {

        }

       /// <summary>

        /// Clean up any resources being used.

        /// </summary>

        protected override void Dispose( bool disposing )

        {

        if(disposing && components != null)

        {

        components.Dispose();

        }

        base.Dispose(disposing);

        }

        #endregion

       // 连接字符串常量

        const string szConn = "server=(local)\\taoyi;uid=sa;pwd=;"

        + "initial catalog=mydata;data source=taoyi";

       [WebMethod]

        public String About()

        {

        return "这是一个C#编写的Web Service演示程序!";

        }

        // 返回其中一个WebServiceDemo表

        [WebMethod]

        public DataSet GetServiceDemoTable()

        {

        DataSet sqlDs = new DataSet();

        DataAccess dataAcc = new DataAccess(szConn);

        string szSql = "Select * From WebServiceDemo";

        sqlDs = dataAcc.GetDataset(szSql,"Demo");

       return sqlDs;

        }

        // 返回由用户指定的查询

        [WebMethod]

        public DataSet GetByUser(string szCommandText)

        {

        DataSet sqlDs = new DataSet();

        DataAccess dataAcc = new DataAccess(szConn);

        sqlDs = dataAcc.GetDataset(szCommandText);

       return sqlDs;

        }

        }

       æ˜¯ä¸æ˜¯å¾ˆç®€å•å“¦ï¼Œå°±åªè¿™ä¹ˆç‚¹ï¼Œå‘µå‘µ~,不过也可以说明问题的了。这个类中声明了三个WEB方法,有没有发觉呢?每个方法的前面都加了[WebMethod],表示该方法为WEB方法。呵呵,如果你想要你写的函数可以让WEB应用程序调用的话,这个可不能少的啦~,不然WEB应用程序就无法调用的。

       åˆ°æ­¤ä¸€ä¸ªWEB服务就完成了,点击运行看看,如果没什么错的话,就会出现如下的WEB页面服务描述:

       Service1

       The following operations are supported. For a formal definition, please review the Service Description.

       * GetByUser

       * GetServiceDemoTable

       * About

       .....(下面还有很多)

       å…¶ä¸­ä»£æ˜Ÿå·çš„就是先前在函数前加了[WebMethod]的函数。在出现在页面中你可以单击相应的函数,然后就会跳到调用页面,你可以在相应的文本框中(如果函数有参数的话)输入相应的参数,点而调用按钮,那么就可以看到函数返回的结果了(前提是函数调用无错的话),不过全是XML格式的文本。比如我的GetServiceDemoTable函数调用的结果如下:

       <?xml version="1.0" encoding="utf-8" ?>

       - <DataSet xmlns=":xml-msdata">

       - <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="zh-CN">

       - <xs:complexType>

       - <xs:choice maxOccurs="unbounded">

       - <xs:element name="Demo">

       - <xs:complexType>

       - <xs:sequence>

        <xs:element name="ID" type="xs:int" minOccurs="0" />

        <xs:element name="szUser" type="xs:string" minOccurs="0" />

        <xs:element name="szSex" type="xs:string" minOccurs="0" />

        <xs:element name="szAddr" type="xs:string" minOccurs="0" />

        </xs:sequence>

        </xs:complexType>

        </xs:element>

        </xs:choice>

        </xs:complexType>

        </xs:element>

        </xs:schema>

       - <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

       - <NewDataSet xmlns="">

       - <Demo diffgr:id="Demo1" msdata:rowOrder="0">

        <ID>1</ID>

        <szUser>taoyi</szUser>

        <szSex>男</szSex>

        <szAddr>四川泸州</szAddr>

        </Demo>

       - <Demo diffgr:id="Demo2" msdata:rowOrder="1">

        <ID>2</ID>

        <szUser>xiner</szUser>

        <szSex>女</szSex>

        <szAddr>四川宜宾</szAddr>

        </Demo>

        </NewDataSet>

        </diffgr:diffgram>

        </DataSet>

       åˆ°æ­¤ä¸ºè‡³ï¼ŒWeb Service程序就已经算是完成了。

       ä¸‹é¢è¦åšçš„是写一个WEB应用程序来测试我写的这个Web Service了,看看能不能达到想要的结果。建立Web应用程序的步骤如下:

       ä¸€ã€æ–°å»ºä¸€ä¸ªASP.Net Web Application工程,与创建Web Service的第一步一样,只是工程类型不一样罢了。我这里工程名为WebServiceDemoTest,完整的为,如果大家有什么好的资源和经验欢迎和我交流.

        引入DBUnit

       çŽ°å®žç³»ç»Ÿä¸­é€šå¸¸ä¼šæœ‰ä¸€äº›å…·æœ‰å¤–部依赖性的对象,这些对象和数据库或者其他对象存在诸多关联。如果我们对这样的对象编写单元和组件级测试的话,可以想象将是非常麻烦的一件事.因为这种外部依赖性的存在,使的我们很难将对象孤立出来进行测试。经常提及的白盒测试法,基本上就是通过控制对象的外部依赖性来达到隔离对象的目的,使的可以操作这些对象的状态和相关行为。

        运用 模拟对象(mock objects)

       æˆ–者stubs,就是一个控制对象外部依赖性的解决方案。通过隔离那些关联的数据库访问类,象JDBC的相关操作类,对于控制对象外部依赖性将是很有效的。但模拟对象的解决方案对一些特殊的应用系统架构就显得力不从心了,象那些运用了EJB的CMP(container-managed

       persistence)或者 JDO(java Data

       Objects)的应用系统架构,在这些架构里,数据库的访问对象是在最底层的而且很隐蔽。

        由Manuel Laflamme

       ç¼–写的开放源代码的DBUnit架构体系,对于控制系统内部的数据库依赖性提供了一个非常不错的解决方案。他允许程序员在整个的测试过程中自由的管理控制数据库的状态,这很重要。利用DBUnit,在测试之前,我们可以给目标数据库植入我们需要的数据集,而且,在测试完毕后,数据库完全能够回溯到测试前的状态。

       åœ¨å¾ˆå¤šæˆåŠŸçš„软件项目中,测试自动化往往是关键的层面。DBUnit允许开发人员创建测试用例代码,在这些测试用例的生命周期内我们可以很好的控制数据库的状态。而且,这些测试用例是很容易实现自动化的。这样在测试过程中我们无须对它进行人工的干预,为人工干预造成的后果而担心就更没必要了。

        简单介绍

       é…ç½®ä½¿ç”¨DBUnit的第一步我们首先需要知道如何生成数据库schema,这个文件是XML格式的,其中包括了数据库的表及相关数据信息。

       ä¾‹å¦‚,这里有一个数据库表employee

       ï¼Œæˆ‘们可以用SQL的形式这样将他表示出来。

       è€Œä¸”,我们可以看到,一个简单的数据集可以这样表示

       åœ¨DBUnit中,上面这个表和抽样数据信息可以用XML文件的形式这样表示:

        <EMPLOYEE employee_uid='1'

        start_date='--'

        first_name='Andrew'

        ssn='xxx-xx-xxxx'

        last_name='Glover' />

        这个生成的XML格式的文件可以作为系统所需的所有种子文件(seed

       files)的样本模版.

       ä¸ºç›¸äº’关联的测试场景创建多个种子文件是一个很有效的策略,就象通过不同的数据库文件来区分隔离数据库状态是一个道理。多种子文件策略可以将我们的测试目标锁定到较小的范围,目标数据可以只针对数据库的表,而不是整个数据库。

        为了给目标数据库植入不同的职员记录,我们需要的XML数据文件如下所示:

        <?xml version='1.0' encoding='UTF-8'?>

        <dataset>

        <EMPLOYEE employee_uid='1'

        start_date='--'

        first_name='Drew' ssn='--'

        last_name='Smith' />

        <EMPLOYEE employee_uid='2'

        start_date='--'

        first_name='Nick' ssn='--'

        last_name='Marquiss' />

        <EMPLOYEE employee_uid='3'

        start_date='--'

        first_name='Jose' ssn='--'

        last_name='Whitson' />

        </dataset>

       çŽ°åœ¨ï¼Œè¦è®©DBUnit和我们所需的数据库schema一起工作了,对于程序员来说,我们使用DBUnit进行测试可以有两种选择:通过直接编码方式进行测试或者与Ant结合.

        编码方式

       DBUnit框架提供了一个基本的抽象测试用例类,叫做DatabaseTestCase,它是JUnit框架中的基础类TestCase的子类。如果我们使用这个类必须首先实现两个钩子方法(hook

       methods):getConnection()和getDataSet().

       æ–¹æ³•getConnection()需要返回一个IDatabaseConnection类型的对象,这个对象是一个基于普通JDBC连接的包装类。例如,下面的代码段演示了在MySQL数据库环境下,IDatabaseConnection类型连接对象的创建方法。

        protected IDatabaseConnection getConnection()

        throws Exception {

        Class driverClass = Class.forName("org.gjt.mm.mysql.Driver");

        Connection jdbcConnection = DriverManager.getConnection(

       "jdbc:mysql://.0.0.1/hr", "hr", "hr");

        return new DatabaseConnection(jdbcConnection);

       }

       æ–¹æ³•getDataSet()返回一个IDataSet类型对象,其实,说白了,他就是我们先前提到的XML数据的种子文件的另一种表现形式。

        protected IDataSet getDataSet() throws Exception {

        return new FlatXmlDataSet(

        new

       FileInputStream("hr-seed.xml"));

        }

       æœ‰äº†è¿™ä¸¤ä¸ªåŸºæœ¬çš„方法以后,DBUnit就可以按照它预先缺省的行为工作了。DatabaseTestCase类提供了两个fixture(我叫它固件,不知仁兄同意否?)方法来控制测试前和测试后的数据库状态。这两个方法就是:

       getSetUpOperation() 和 getTearDownOperation().

       ä¸€ç§é«˜æ•ˆçš„实施方案就是让getSetUpOperation()方法执行REFRESH操作,通过这个操作,我们可以用种子文件中的数据去更新目标数据库里的数据。接下来,就是getTearDownOperation(),让他去执行一个NONE操作,也就是什么也不执行。

        protected DatabaseOperation getSetUpOperation()

        throws

       Exception {

        return DatabaseOperation.REFRESH;

        }

        protected DatabaseOperation getTearDownOperation()

        throws

       Exception {

        return DatabaseOperation.NONE;

        }

       è¿˜æœ‰ä¸€ç§æœ‰æ•ˆçš„方法就是在getSetUpOperation()方法中执行CLEAN_INSERT操作,这样首先会将目标数据库中与我们提供的种子文件一致的数据删除,然后将我们提供的数据插入到数据库中。这个实施顺序保证了我们对数据库的精确控制。

        代码样例

       åœ¨ä¸€ä¸ªåŸºäºŽJ2EE的人力资源系统中,我们很希望对某个数据操作周期实现测试自动化,这个操作周期包括职员的新增,检索,更新和删除。远程接口定义了下列的业务方法(为了简洁清楚,省略了方法中的throws子句).

       //译者注:这里的EmployeeValueObject类型对象,译者认为是代表职员实体信息的对象。

       public void createEmployee( EmployeeValueObject emplVo )

       public EmployeeValueObject getEmployeeBySocialSecNum( String ssn )

       public void updateEmployee( EmployeeValueObject emplVo )

       public void deleteEmployee( EmployeeValueObject emplVo )

        测试getEmployeeBySocialSecNum()方法

       éœ€è¦æ¤å…¥ä¸€æ¡æ•°æ®åˆ°ç›®æ ‡æ•°æ®åº“中,另外,测试deleteEmployee()方法和updateEmployee()方法时,同样也是在先前植入的这条记录的基础上进行。最后,测试类会首先利用createEmployee()方法创建一条记录,同时我们需要校验执行这个方法时,是否会有异常发生。

       ä¸‹é¢è¿™ä¸ªDBUnit种子文件,叫做"employee_hr_seed.xml",下面将用到这个文件。

        <?xml version='1.0' encoding='UTF-8'?>

        <dataset>

        <EMPLOYEE employee_uid='1'

        start_date='--'

        first_name='Drew' ssn='--'

        last_name='Smith' />

        <EMPLOYEE employee_uid='2'

        start_date='--'

        first_name='Nick' ssn='--'

        last_name='Marquiss' />

        <EMPLOYEE employee_uid='3'

        start_date='--'

        first_name='Jose' ssn='--'

        last_name='Whitson' />

        </dataset>

        测试类 EmployeeSessionFacadeTest

       ,需要扩展DBUnit的基础类DatabaseTestCase并且必须提供对getConnection()和getDataSet()方法的实现,在getConnection()方法中将获得与EJB容器初始化时一样的数据库实例,getDataSet()方法负责读取上面提及的employee_hr_seed.xml文件的数据。

       æµ‹è¯•æ–¹æ³•ç›¸å½“简单,因为DBUnit已经为我们处理了复杂的数据库生命周期任务。为了测试getEmployeeBySocialSecNum()方法,只需要简单的传递一个存在于种子文件中的社保代码号即可,比如

       "--".

       //译者注:EmployeeFacade 类型对象,译者认为是代表底层数据库数据的映射体

       public void testFindBySSN() throws Exception{

        EmployeeFacade facade = //obtain somehow

        EmployeeValueObject vo =

        facade.getEmployeeBySocialSecNum("--");

        TestCase.assertNotNull("vo shouldn't be null", vo);

        TestCase.assertEquals("should be Drew",

        "Drew", vo.getFirstName());

        TestCase.assertEquals("should be Smith",

        "Smith", vo.getLastName());

       }

       ä¸ºäº†ç¡®ä¿æ“ä½œå‘¨æœŸä¸­çš„创建职员方法createEmployee()没有问题,我们只需简单的执行一下这个方法,然后校验一下看有没有异常抛出,另外,下一步我们要做的就是在这条新增的记录上进行查找操作,看是否可以找到刚创建的记录。

        public void testEmployeeCreate() throws Exception{

        EmployeeValueObject empVo = new EmployeeValueObject();

        empVo.setFirstName("Noah");

        empVo.setLastName("Awan");

        empVo.setSSN("--");

        EmployeeFacade empFacade = //obtain from somewhere

        empFacade.createEmployee(empVo);

        //perform a find by ssn to ensure existence

       }

       æµ‹è¯•updateEmployee()方法包括四步,首先查找我们需要被更新的那条记录,然后更新它,紧接着,重新查找这条记录,确认更新操作是否有效。

        public void testUpdateEmployee() throws Exception{

        EmployeeFacade facade =//obtain facade

        EmployeeValueObject vo =

       facade.getEmployeeBySocialSecNum("--");

        TestCase.assertNotNull("vo was null", vo);

        TestCase.assertEquals("first name should be Jose", "Jose",

       vo.getFirstName());

        vo.setFirstName("Ramon");

        facade.updateEmployee(vo);

        EmployeeValueObject newVo =

       facade.getEmployeeBySocialSecNum("--");

        TestCase.assertNotNull("vo was null", newVo);

        TestCase.assertEquals("name should be Ramon", "Ramon",

       newVo.getFirstName());

       }

       ç¡®ä¿æ•°æ®æ“ä½œå‘¨æœŸä¸­çš„删除操作deleteEmployee()的方法和testUpdateEmployee()方法基本类似。

       å®ƒåˆ†ä¸ºä¸‰æ­¥ï¼šé¦–先查找一个已存在的记录实体,然后移除,最后再对相同的记录进行查找,确认这条记录没有被查到。

       public void testDeleteEmployee() throws Exception{

        EmployeeFacade facade = //obtain facade

        EmployeeValueObject vo = facade.getEmployeeBySocialSecNum("--");

        TestCase.assertNotNull("vo was null", vo);

        facade.deleteEmployee(vo);

        try{

        EmployeeValueObject newVo =

       facade.getEmployeeBySocialSecNum("--");

        TestCase.fail("returned removed employee");

        }catch(Exception e){

        //ignore

        }

       }

       ä¸Šè¿°è¿™äº›æµ‹è¯•ä»£ç å¾ˆç®€å•ä¹Ÿå¾ˆå®¹æ˜“理解.因为这些代码唯一的职责就是测试,已经完全从系统程序代码中独立出来,这使测试变的简单。并且,这些测试用例的自动化也很容易实现。

        与Ant的结合

       ç›¸å¯¹äºŽæ‰©å±•DBUnit中的基础类DatabaseTestCase,DBUnit框架中自带Ant功能,允许我们可以在Ant的build.xml文件中控制数据库的状态.这个功能是相当强大的,因为对于作成的诸多测试用例,它提供了一个相当简洁的解决方案。比如。在Ant中运行JUnit测试,就象下面定义一个任务一样简单明了。

       <junit printsummary="yes" haltonfailure="yes">

        <formatter type="xml"/>

        <batchtest fork="yes"

        todir="${ reports.tests}">

        <fileset dir="${ src.tests}">

        <include name="**/*Test.java"/>

        </fileset>

        </batchtest>

       </junit>

       DBUnit任务过程中,为了在Junit任务前后控制数据库的状态,我们需要创建一个"setup"操作,在这个操作中种子文件中的数据内容会被插入的数据库中。

       <taskdef name="dbunit"

        classname="org.dbunit.ant.DbUnitTask"/>

       <dbunit driver=" org.gjt.mm.mysql.Driver "

        url=" jdbc:mysql://.0.0.1/hr "

        userid="hr"

        password="hr">

        <operation type="INSERT"

        src="seedFile.xml"/>

       </dbunit>

       ç„¶åŽï¼Œè¿˜éœ€è¦ä¸€ä¸ª"tear

       down"操作,在这个操作中,"setup"操作插入的记录被从目标数据库中删除了。

       <dbunit driver=" org.gjt.mm.mysql.Driver "

        url=" jdbc:mysql://.0.0.1/hr "

        userid="hr"

        password="hr">

        <operation type="DELETE"

        src="seedFile.xml"/>

       </dbunit>

       ç”¨ä¸Šé¢çš„代码来包装JUnit任务,能够在批量测试前有效的装载数据到目标数据库中,并且在测试结束后,将已装载的全部数据删除。

       <taskdef name="dbunit"

        classname="org.dbunit.ant.DbUnitTask"/>

       <!-- set up operation -->

       <dbunit driver=" org.gjt.mm.mysql.Driver "

        url=" jdbc:mysql://.0.0.1/hr "

        userid="hr"

        password="hr">

        <operation type="INSERT"

        src="seedFile.xml"/>

       </dbunit>

       <!-- run all tests in the source tree -->

       <junit printsummary="yes" haltonfailure="yes">

        <formatter type="xml"/>

        <batchtest fork="yes" todir="${ reports.tests}">

        <fileset dir="${ src.tests}">

        <include name="**/*Test*.java"/>

        </fileset>

        </batchtest>

       </junit>

       <!-- tear down operation -->

       <dbunit driver=" org.gjt.mm.mysql.Driver "

        url=" jdbc:mysql://.0.0.1/hr "

        userid="hr"

        password="hr">

        <operation type="DELETE"

        src="seedFile.xml"/>

       </dbunit>

        结论

       èƒ½å¤Ÿåœ¨æµ‹è¯•å‘¨æœŸå†…管理数据库的状态,DBUnit框架的这个功能特性使得测试用例代码的创建和应用的周期大大缩短。而且,通过控制数据库这个主要的依赖对象,使的利用DBUnit框架的的测试更容易自动化。

       DBUnit精妙的设计,使的学习使用它变得很简单。在你的测试方案中,如果你能够正确的使用它,那么带来的将是代码稳定性方面的大幅度增强,当然还会使你的开发团队信心倍增。

求决策树源代码。最好使用matlab实现。源码

       function [Tree RulesMatrix]=DecisionTree(DataSet,源码排名互点源码AttributName)

       %输入为训练集,为离散后的源码相册翻书源码数字,如记录1:1 1 3 2 1;

       %前面为属性列,源码最后一列为类标

       if nargin<1

        error('请输入数据集');

       else

        if isstr(DataSet)

        [DataSet AttributValue]=readdata2(DataSet);

        else

        AttributValue=[];

        end

       end

       if nargin<2

        AttributName=[];

       end

        Attributs=[1:size(DataSet,源码2)-1];

        Tree=CreatTree(DataSet,Attributs);

        disp([char() 'The Decision Tree:']);

        showTree(Tree,0,0,1,AttributValue,AttributName);

        Rules=getRule(Tree);

        RulesMatrix=zeros(size(Rules,1),size(DataSet,2));

        for i=1:size(Rules,1)

        rule=cell2struct(Rules(i,1),{ 'str'});

        rule=str2num([rule.str([1:(find(rule.str=='C')-1)]) rule.str((find(rule.str=='C')+1):length(rule.str))]);

        for j=1:(length(rule)-1)/2

        RulesMatrix(i,rule((j-1)*2+1))=rule(j*2);

        end

        RulesMatrix(i,size(DataSet,2))=rule(length(rule));

        end

       end

       function Tree=CreatTree(DataSet,Attributs) %决策树程序 输入为:数据集,属性名列表

        %disp(Attributs);

        [S ValRecords]=ComputEntropy(DataSet,源码0);

        if(S==0) %当样例全为一类时退出,返回叶子节点类标

        for i=1:length(ValRecords)

        if(length(ValRecords(i).matrix)==size(DataSet,源码1))

        break;

        end

        end

        Tree.Attribut=i;

        Tree.Child=[];

        return;

        end

        if(length(Attributs)==0) %当条件属性个数为0时返回占多数的类标

        mostlabelnum=0;

        mostlabel=0;

        for i=1:length(ValRecords)

        if(length(ValRecords(i).matrix)>mostlabelnum)

        mostlabelnum=length(ValRecords(i).matrix);

        mostlabel=i;

        end

        end

        Tree.Attribut=mostlabel;

        Tree.Child=[];

        return;

        end

        for i=1:length(Attributs)

        [Sa(i) ValRecord]=ComputEntropy(DataSet,i);

        Gains(i)=S-Sa(i);

        AtrributMatric(i).val=ValRecord;

        end

        [maxval maxindex]=max(Gains);

        Tree.Attribut=Attributs(maxindex);

        Attributs2=[Attributs(1:maxindex-1) Attributs(maxindex+1:length(Attributs))];

        for j=1:length(AtrributMatric(maxindex).val)

        DataSet2=[DataSet(AtrributMatric(maxindex).val(j).matrix',1:maxindex-1) DataSet(AtrributMatric(maxindex).val(j).matrix',maxindex+1:size(DataSet,2))];

        if(size(DataSet2,1)==0)

        mostlabelnum=0;

        mostlabel=0;

        for i=1:length(ValRecords)

        if(length(ValRecords(i).matrix)>mostlabelnum)

        mostlabelnum=length(ValRecords(i).matrix);

        mostlabel=i;

        end

        end

        Tree.Child(j).root.Attribut=mostlabel;

        Tree.Child(j).root.Child=[];

        else

        Tree.Child(j).root=CreatTree(DataSet2,Attributs2);

        end

        end

       end

       function [Entropy RecordVal]=ComputEntropy(DataSet,attribut) %计算信息熵

        if(attribut==0)

        clnum=0;

        for i=1:size(DataSet,1)

        if(DataSet(i,size(DataSet,2))>clnum) %防止下标越界

        classnum(DataSet(i,size(DataSet,2)))=0;

        clnum=DataSet(i,size(DataSet,2));

        RecordVal(DataSet(i,size(DataSet,2))).matrix=[];

        end

        classnum(DataSet(i,size(DataSet,2)))=classnum(DataSet(i,size(DataSet,2)))+1;

        RecordVal(DataSet(i,size(DataSet,2))).matrix=[RecordVal(DataSet(i,size(DataSet,2))).matrix i];

        end

        Entropy=0;

        for j=1:length(classnum)

        P=classnum(j)/size(DataSet,1);

        if(P~=0)

        Entropy=Entropy+(-P)*log2(P);

        end

        end

        else

        valnum=0;

        for i=1:size(DataSet,1)

        if(DataSet(i,attribut)>valnum) %防止参数下标越界

        clnum(DataSet(i,attribut))=0;

        valnum=DataSet(i,attribut);

        Valueexamnum(DataSet(i,attribut))=0;

        RecordVal(DataSet(i,attribut)).matrix=[]; %将编号保留下来,以方便后面按值分割数据集

        end

        if(DataSet(i,源码size(DataSet,2))>clnum(DataSet(i,attribut))) %防止下标越界

        Value(DataSet(i,attribut)).classnum(DataSet(i,size(DataSet,2)))=0;

        clnum(DataSet(i,attribut))=DataSet(i,size(DataSet,2));

        end

        Value(DataSet(i,attribut)).classnum(DataSet(i,size(DataSet,2)))= Value(DataSet(i,attribut)).classnum(DataSet(i,size(DataSet,2)))+1;

        Valueexamnum(DataSet(i,attribut))= Valueexamnum(DataSet(i,attribut))+1;

        RecordVal(DataSet(i,attribut)).matrix=[RecordVal(DataSet(i,attribut)).matrix i];

        end

        Entropy=0;

        for j=1:valnum

        Entropys=0;

        for k=1:length(Value(j).classnum)

        P=Value(j).classnum(k)/Valueexamnum(j);

        if(P~=0)

        Entropys=Entropys+(-P)*log2(P);

        end

        end

        Entropy=Entropy+(Valueexamnum(j)/size(DataSet,1))*Entropys;

        end

        end

       end

       function showTree(Tree,level,value,branch,AttributValue,AttributName)

        blank=[];

        for i=1:level-1

        if(branch(i)==1)

        blank=[blank ' |'];

        else

        blank=[blank ' '];

        end

        end

        blank=[blank ' '];

        if(level==0)

        blank=[' (The Root):'];

        else

        if isempty(AttributValue)

        blank=[blank '|_____' int2str(value) '______'];

        else

        blank=[blank '|_____' value '______'];

        end

        end

        if(length(Tree.Child)~=0) %非叶子节点

        if isempty(AttributName)

        disp([blank 'Attribut ' int2str(Tree.Attribut)]);

        else

        disp([blank 'Attribut ' AttributName{ Tree.Attribut}]);

        end

        if isempty(AttributValue)

        for j=1:length(Tree.Child)-1

        showTree(Tree.Child(j).root,level+1,j,[branch 1],AttributValue,AttributName);

        end

        showTree(Tree.Child(length(Tree.Child)).root,level+1,length(Tree.Child),[branch(1:length(branch)-1) 0 1],AttributValue,AttributName);

        else

        for j=1:length(Tree.Child)-1

        showTree(Tree.Child(j).root,level+1,AttributValue{ Tree.Attribut}{ j},[branch 1],AttributValue,AttributName);

        end

        showTree(Tree.Child(length(Tree.Child)).root,level+1,AttributValue{ Tree.Attribut}{ length(Tree.Child)},[branch(1:length(branch)-1) 0 1],AttributValue,AttributName);

        end

        else

        if isempty(AttributValue)

        disp([blank 'leaf ' int2str(Tree.Attribut)]);

        else

        disp([blank 'leaf ' AttributValue{ length(AttributValue)}{ Tree.Attribut}]);

        end

        end

       end

       function Rules=getRule(Tree)

        if(length(Tree.Child)~=0)

        Rules={ };

        for i=1:length(Tree.Child)

        content=getRule(Tree.Child(i).root);

        %disp(content);

        %disp([num2str(Tree.Attribut) ',' num2str(i) ',']);

        for j=1:size(content,1)

        rule=cell2struct(content(j,1),{ 'str'});

        content(j,1)={ [num2str(Tree.Attribut) ',' num2str(i) ',' rule.str]};

        end

        Rules=[Rules;content];

        end

        else

        Rules={ ['C' num2str(Tree.Attribut)]};

        end

       end