<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>junjie314</title>
    <description>当他临山观云，窗台斜倚，闭目写下世界某处的奇险壮丽， 
顺手雕刻恋人心中的幽暗折曲，长安城正是人声鼎沸，炊烟向晚， 
飘溢出窗棂流窜在街角的欢醉夜曲，始终不曾缺少过他的传奇。 

最后的浪漫正消逝，横死在激爆八卦与猜忌耳语， 
粗野标题主宰著世纪，诗人即将绝迹，他弹笑落笔， 
终将读诗翻转成一个文字盛世的流行，初成的少年争唱他笔下的动魄惊心。 

他是李白，否则围绕他的奇迹，将没有一个解释合理。 

</description>
    <link>http://junjie314.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>关于Portal</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/162655" style="color:red;">http://junjie314.javaeye.com/blog/162655</a>&nbsp;
          发表时间: 2008年02月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这里所说的Portal是指JCP-JSR168规范所描述的：Portal是一个基于Web的应用，通常它提供个性化、单点登录、内容集成和显示等功能。Portal技术包括三个方面：<br /><br />1）  Portal服务器(Portal Server)；<br /><br />2）  Portlet容器；(Portlet Container)<br /><br />3）  Portlet。<br /><br />1) Portal Server 的定义是<br /><br />一个 Portal（门户网站）就是指一个 Web-based 的系统，通常都会提供个人化设置、单一登陆、以及由各种不同来源或不同网站取得各式各样的信息，并且将这些信息放在网页之中组合而成的呈现平台，门户网站会有精巧的个人化设置去提供定制的网页，当不同等级的使用者来浏览该页面将获得不同的信息内容。 <br /><br />负责接收HTTP请求，调用portlet，并将portlet产生的内容聚集到portal page返回给客户。<br /><br />2) Portlet Container 的定义是<br /><br />portlet container 是提供 portlets 执行的环境，包含了许多 portlets 并且管理他们的生命周期，他也会永远保存着 portlets 的喜好设置，一个 portlet container 接收到来自 portal 的请求后，接着将这个请求传递给存在 container 的 portlet 执行。portlet container 没有义务去组合 portlets 产生的信息內容，这个工作必须由 portal 来处理。portal 和 portlet container 可以放在一起视为同一个系统的组件，或者分开成为两个独立的组件。 <br /><br />负责提供portlet的运行时环境，管理portlet的生命周期，还负责提供portlet持久化能力。<br /><br />3) Portlet 的定义是<br /><br />一个 Portlet 是以 Java 技术为技术的 Web 组件，由 Portlet Container 所管理，专门处理客户的 request 以及产生各种动态的信息内容。Portlets 为可插式 ( pluggable ) 的客户界面组件，提供呈现层成为一个信息系统。这些由 portlet 产生的内容也被称为片段 (fragment)，而片段是具有一些规则的Markup( HTML、XHTML、WML )，而且可以和其他的片段组合而成一个复杂的文件。而 Portlet 中的内容正常来说是与其他 Portlet 的内容聚合而成为一个 Portal 网页。而 Portlet 的生命周期是被 Portlet Container 所管理控制的。客户端和 portlets 的互动是由 portal 通过典型的 request/response 方式实现，正常来说，客户会和 portlets 所产生的内容互动，举例来说，根据下一步的连接或者是确认送出的表单，结果 portal 将会接收到 portlet 的动作，将这个处理状况转向到目标 portlet。这些 portlet 内容的产生可能会因为不同的使用者而有不同的变化，完全是根据客户对于这个 portlet 的设置。<br /><br />Portal主要是解决企业信息和应用的前端集成问题，它负责连结企业后台EAI，集成企业的结构和非结构化信息，并提供统一的访问企业信息和应用的入口。<br /><br />(摘自JSR168规范文档)<br /><br />portlet 与 servlet 的关系<br />Portlet 和 Servlet 算是兄弟有那么一点点相似却又有那么一点点不同，因为 Servlet 和 Portlet 不尽然相同，所以研究小組決定将 portlets 定义成为一个新的组件，因此定义了 portlets 一个新的并且明确的界面与行为。为了尽可能与现有的 servlet 结合达到重复使用的目的，portlet 的规范利用了 servlet 的规范，许多观念都很相似的，结合 portlets、servlets 及 jsp 在同一个网站系统中，我们称为 portlet application 。在同一个 portlet application 中，他们将分享同一个 classloader，context 及 session。 <br /><br />1) Portlet 和 Servlet 的相似之处<br /><br />@ portlets 也是 Java 技术的 web 组件<br />@ portlets 也是有特定的 container 在管理<br />@ portlets 可以动态产生各种内容<br />@ portlets 的生命周期由 container 所管理<br />@ portlets 和客户端的互动是通过 request/response 的机制 <br /><br />2) Portlet 和 Servlet 也有一些不同<br /><br />@ portlets 只产生 markup 信息片段，不是完整的网页文件。而 Portal 会将所有的 Portlet markup 信息片 段放到一个完整的 Portal 网页。<br />@ portlets 不会和 URL 有直接的关系<br />@ 客户端必须通过 portal 系统才能和 portlets 互动<br />@ portlets 有一些定义好的 request 处理，action request 以及 render request。<br />@ portlets 默认定义 portlet modes 及窗口状态可以指出在网页中该 portlet 的哪个功能正在执行及现在的 状态。<br />@ portlets 可以在同一个 portal 网页之中存在多个。 <br /><br />3) Portlet 有一些附加的功能是 Servlet 所没有的<br /><br />@ Portlets 能够存取及储存永久配置文件及定制资料。<br />@ portlets 可以存取使用者数据<br />@ portlets 具有 URL 的重写功能在文件中去动态建立连结，允许 portal server 不用去知道如何在网页的片 段之中建立连结及动作。<br />@ portlets 可以储存临时性的数据在 portlet session 之中，拥有两个不同的范围：<br />application-wide scope 及 portlet private scope 。 <br /><br />4) Portlet 不具有一些功能， 但是 Servlet 却有提供<br /><br />@ servlet 具有设置輸出的文字编码( character set encoding)方式<br />@ servlet 可以设置 HTTP 输出的 header<br />@ servlet 才能夠接收客户对于 portal 发出的 URL 请求<br /><br />基于Portal开发项目的优势<br />1、可以与以后新开发的或已集成到Portal中的企业应用实现无缝集成。<br /><br />2、可以分享Portal服务器和Portlet容器提供的种种功能。这要视Portal服务器提供商而定。<br /><br />3、由于Portlet已规范化（JSR168），所以应用中开发的Portlet可以部署在不同的Portal服务器上。
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/162655#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 16 Feb 2008 16:57:58 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/162655</link>
        <guid>http://junjie314.javaeye.com/blog/162655</guid>
      </item>
      <item>
        <title>IE与firefox在Javascript上的区别(转)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/162638" style="color:red;">http://junjie314.javaeye.com/blog/162638</a>&nbsp;
          发表时间: 2008年02月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          以下以 ie 代替 internet explorer，以 mf 代替 mozzila firefox <br />1. document.form.item 问题 <br />(1)现有问题： <br />现有代码中存在许多 document.formname.item("itemname") 这样的语句，不能在 mf 下运行 <br />(2)解决方法： <br />改用 document.formname.elements["elementname"] <br />(3)其它 <br />参见 2 <br /><br />2. 集合类对象问题 <br />(1)现有问题： <br />现有代码中许多集合类对象取用时使用 ()，ie 能接受，mf 不能。 <br />(2)解决方法： <br />改用 [] 作为下标运算。如：document.forms("formname") 改为 document.forms["formname"]。 <br />又如：document.getelementsbyname("inputname")(1) 改为 document.getelementsbyname("inputname")[1] <br />(3)其它 <br /><br />3. window.event <br />(1)现有问题： <br />使用 window.event 无法在 mf 上运行 <br />(2)解决方法： <br />mf 的 event 只能在事件发生的现场使用，此问题暂无法解决。可以这样变通： <br />原代码(可在ie中运行)： <br />提交" onclick="javascript:gotosubmit()"/> <br />... <br /><br /><br />新代码(可在ie和mf中运行)： <br />提交" onclick="javascript:gotosubmit(event)"/> <br />... <br /><br />此外，如果新代码中第一行不改，与老代码一样的话(即 gotosubmit 调用没有给参数)，则仍然只能在ie中运行，但不会出错。所以，这种方案 tpl 部分仍与老代码兼容。 <br /><br />4. html 对象的 id 作为对象名的问题 <br />(1)现有问题 <br />在 ie 中，html 对象的 id 可以作为 document 的下属对象变量名直接使用。在 mf 中不能。 <br />(2)解决方法 <br />用 getelementbyid("idname") 代替 idname 作为对象变量使用。 <br /><br />5. 用idname字符串取得对象的问题 <br />(1)现有问题 <br />在ie中，利用 eval(idname) 可以取得 id 为 idname 的 html 对象，在mf 中不能。 <br />(2)解决方法 <br />用 getelementbyid(idname) 代替 eval(idname)。 <br /><br />6. 变量名与某 html 对象 id 相同的问题 <br />(1)现有问题 <br />在 mf 中，因为对象 id 不作为 html 对象的名称，所以可以使用与 html 对象 id 相同的变量名，ie 中不能。 <br />(2)解决方法 <br />在声明变量时，一律加上 var ，以避免歧义，这样在 ie 中亦可正常运行。 <br />此外，最好不要取与 html 对象 id 相同的变量名，以减少错误。 <br />(3)其它 <br />参见 问题4 <br /><br />7. event.x 与 event.y 问题 <br />(1)现有问题 <br />在ie 中，event 对象有 x, y 属性，mf中没有。 <br />(2)解决方法 <br />在mf中，与event.x 等效的是 event.pagex。但event.pagex ie中没有。 <br />故采用 event.clientx 代替 event.x。在ie 中也有这个变量。 <br />event.clientx 与 event.pagex 有微妙的差别（当整个页面有滚动条的时候），不过大多数时候是等效的。 <br /><br />如果要完全一样，可以稍麻烦些： <br />mx = event.x ? event.x : event.pagex; <br />然后用 mx 代替 event.x <br />(3)其它 <br />event.layerx 在 ie 与 mf 中都有，具体意义有无差别尚未试验。 <br /><br /><br />8. 关于frame <br />(1)现有问题 <br />在 ie中 可以用window.testframe取得该frame，mf中不行 <br />(2)解决方法 <br />在frame的使用方面mf和ie的最主要的区别是： <br />如果在frame标签中书写了以下属性： <br /><br />那么ie可以通过id或者name访问这个frame对应的window对象 <br />而mf只可以通过name来访问这个frame对应的window对象 <br />例如如果上述frame标签写在最上层的window里面的htm里面，那么可以这样访问 <br />ie： window.top.frameid或者window.top.framename来访问这个window对象 <br />mf： 只能这样window.top.framename来访问这个window对象 <br /><br />另外，在mf和ie中都可以使用window.top.document.getelementbyid("frameid")来访问frame标签 <br />并且可以通过window.top.document.getelementbyid("testframe").src = 'xx.htm'来切换frame的内容 <br />也都可以通过window.top.framename.location = 'xx.htm'来切换frame的内容 <br />关于frame和window的描述可以参见bbs的‘window与frame’文章 <br />以及/test/js/test_frame/目录下面的测试 <br />----adun 2004.12.09修改 <br /><br />9. 在mf中，自己定义的属性必须getattribute()取得 <br />10.在mf中没有 parentelement parement.children 而用 <br />parentnode parentnode.childnodes <br />childnodes的下标的含义在ie和mf中不同，mf使用dom规范，childnodes中会插入空白文本节点。 <br />一般可以通过node.getelementsbytagname()来回避这个问题。 <br />当html中节点缺失时，ie和mf对parentnode的解释不同，例如 <br /><br />mf中input.parentnode的值为form, 而ie中input.parentnode的值为空节点 <br /><br />mf中节点没有removenode方法，必须使用如下方法 node.parentnode.removechild(node) <br /><br />11.const 问题 <br />(1)现有问题: <br />在 ie 中不能使用 const 关键字。如 const constvar = 32; 在ie中这是语法错误。 <br />(2)解决方法: <br />不使用 const ，以 var 代替。 <br /><br />12. body 对象 <br />mf的body在body标签没有被浏览器完全读入之前就存在，而ie则必须在body完全被读入之后才存在 <br /><br />13. url encoding <br />在js中如果书写url就直接写&不要写&例如var url = 'xx.jsp?objectname=xx&objectevent=xxx'; <br />frm.action = url那么很有可能url不会被正常显示以至于参数没有正确的传到服务器 <br />一般会服务器报错参数没有找到 <br />当然如果是在tpl中例外，因为tpl中符合xml规范，要求&书写为& <br />一般mf无法识别js中的& <br /><br /><br />14. nodename 和 tagname 问题 <br />(1)现有问题： <br />在mf中，所有节点均有 nodename 值，但 textnode 没有 tagname 值。在 ie 中，nodename 的使用好象 <br />有问题（具体情况没有测试，但我的ie已经死了好几次）。 <br />(2)解决方法： <br />使用 tagname，但应检测其是否为空。 <br /><br />15. 元素属性 <br />ie下 input.type属性为只读，但是mf下可以修改 <br /><br />16. document.getelementsbyname() 和 document.all[name] 的问题 <br /><br />(1)现有问题：在 ie 中，getelementsbyname()、document.all[name] 均不能用来取得 div 元素（是否还有其它不能取的元素还不知道）。
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/162638#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 16 Feb 2008 14:13:27 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/162638</link>
        <guid>http://junjie314.javaeye.com/blog/162638</guid>
      </item>
      <item>
        <title>集合框架中的Map接口的使用</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/155435" style="color:red;">http://junjie314.javaeye.com/blog/155435</a>&nbsp;
          发表时间: 2008年01月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文：http://access1.sun.com/techarticles/CollectionsMap.html<br /><br />1. 导言<br />随着Java[tm] 2标准版中的集合框架的引入，一组通用数据结构接口被整合到了Java[tm] 2 SDK，以简化程序员的工作，使程序员可以专注于业务需求，而不是构造数据对象。这个新的框架为用户提供了一些有用的工具和功能，用户不需要对框架的细节知道很多，就可以很好地使用它。<br /><br />在Java[tm]集合框架中，有两个主要的接口，（1）Collection接口，包含list和set子接口，（2）Map接口。Collection和Map接口之间的主要区别在于：Collection中存储了一组对象，而Map存储关键字/值对。在Map对象中，每一个关键字最多有一个关联的值。一个很好的日常的例子就是把人们的profile信息和他的社会安全号（相当于中国的身份证号）进行关联。社会安全号是关键字，而profile就是对应的人映射到的值。<br /><br /><br />2. Map接口<br /><br />下面的代码片断显示了Map接口的样子：<br /><br /><br />public interface java.util.Map { <br /><br />      //Altering Methods <br />      public Object put(Object key, Object value);    //gets Object with key/value mapping <br />      public Object remove(Object key);               //removes Object with key <br />      public void putAll(java.util.Map);              //put all Map elements into current Map <br />      public void clear();                            //removes all mappings from current Map <br /><br />      //Querying Methods <br />      public Object get(Object key);                  //gets Object with key <br />      public int size();                              //returns number of Map elements <br />      public boolean isEmpty();                       //check if Map is empty <br />      public boolean containsKey(Object);             //Checks if map contains object as key <br />      public boolean containsValue(Object);           //Checks if map contains object as value <br />      public boolean equals(Object);                  //compares specified Object with current Map <br /><br />      //Viewing Methods <br />      public java.util.Set keySet();                  //Gets keys <br />      public java.util.Collection values();           //Gets values <br />      public java.util.Set entrySet();                //Gets mappings <br /><br />      public static interface java.util.Map.Entry {   //a map-entry (single key/value pair) <br />           public Object getKey();                    //returns current entry key <br />           public Object getValue();                  //returns current entry value <br />           public Object setValue(Object value);      //replaces current value with specified value <br />           public boolean equals(Object);             //compares current object with specified object <br />           public int hashCode();                     //returns hashcode with current map-entry <br />      } <br />} <br /><br />Map接口为我们提供了完成下面三种主要的功能的方法：<br /><br />1.    Map 改变 <br />2.    Map 查询 <br />3.    Map 视图 <br /><br />Map的改变方法允许用户改变当前Map的内容，包括关键字/值对的删除、更新和插入。<br /><br />Map的查询方法允许用户从Map中获取关键字/值对。不但有查询Map元素的内容的方法，也有可以用来查询整个Map对象的方法。<br /><br />Map中一共有三种不同的视图可以用来分析关键字/值对。既然映射中的关键字必须唯一，那么，keySet()方法获取的是Map中的关键字的一个Set（Set是唯一数据元素的集合）。values()方法返回映射中值的Collection（Collection是允许存储重复元素的对象的集合）。entrySet()方法返回Map.Entrhy的一个Set。<br /> <br />Map.Entry接口是用来存储单个关键字/值对的。在Map.Entry中有存储和获取单个关键字/值元素的方法。entrySet()方法返回一组实现了Map.Entry接口的对象的Set。Set中的每一个元素都代表了Map中的一个独立的关键字/值对。<br /><br /><br />3. Map 的实现<br /><br />下面的部分将Map的三个通用实现作一个简单介绍： <br /><br />1. java.util.Hashtable <br />2. java.util.HashMap <br />3. java.util.TreeMap <br /><br /><br />3.1 java.util.Hashtable<br /><br />Hashtable对象把关键字对象映射到值对象。提供了允许基于关键字搜索的快速查找的方法。Hashtable是在Java 1.0平台中引入的，而下面将要讨论的HashMap是在Java 1.2平台引入的。Hashtable提供的附加方法（Map接口中没有的）有：<br /><br /><br />public class java.util.Hashtable extends Dictionary implements Cloneable, Map, Serializable { <br /><br />     //Hashtable constructors <br />          //construct a default Hashtable with default capacity and load of 0.75 <br />     public Hashtable();                      <br />          //construct a Hashtable with passed capacity and default load of 0.75  <br />     public Hashtable (int initialCapacity);  <br />          //construct Hashtable with passed capacity and load  <br />     public Hashtable(int initialCapacity, float load);  <br />     public Hashtable(Map);                  //construct Hashtable with passed mapping <br />      <br />     //Hashtable specific methods <br />     public boolean contains(Object);        //checks if Object is in Hashtable  <br />     public Enumeration elements();          //returns Enumeration of elements in Hashtable <br />     public Enumeration keys();              //returns Enumeration of keys in hashtable <br />          //creates shallow copy of Hashtable(structure copied, but not key/values) <br />     public Object clone();                   <br />     public String toString();               //prints out key/value pairs of Hashtable elements <br />          //reorganizes all elements in Hashtable, and increases Hashtable capacity <br />     protected void rehash();                 <br />      <br />     public Object get(Object);              //get Value from passed in key <br />     public Object put(Object key, Object value);      //insert key/value pair <br /><br />} <br /><br />Hashtable类似于常见的关键字映射到值的表格，但是Hashtable提供了提取数据的快速方法。当一个元素插入到Hashtable中时，关键字对象被散列（原文：the name of the Object is hashed，似有不妥），返回的整数值作为值对象在表中存储的索引值。 然后，值对象存储为散列索引所指向的（表格）单元的值（译注：这儿的说法可以理解，但欠准确。在Hashtable的实现中在每个单元中存储的是一个包含了散列码、关键字、值和指向下一个Entry的引用的Map.Entry的实现对象）。如果，另外具有相同散列码的对象也要插入Hashtable，则该对象将被存储在一个原条目开始的链表中。<br />Hashtable的初始容量指示了Hashtable中需要分配的空间。由于Hashtable是一个动态的实体，需要不断地大小缩放来为Hashtable高效地分配空间。装载因子指示了在Hashtable的容量需要自动增长之前，容许的空间的百分比占用。<br />The initial capacity of the Hashtable dictates how many spaces are allocated for Objects in the Hashtable. As a Hashtable is a dynamic entity, constant resizing is required to efficiently allocate space for the Hashtable. The load factor indicates how full percentage wise the Hashtable is allowed to become before the Hashtable's capacity is automatically increased. <br />需要注意的两点是（1）Hashtable是同步的，（2）Hashtable中不允许关键字或值为null。<br />Two things to note are that (1) Hashtable data is synchronized and (2) the null value is not allowed as a key or value in the Hashtable. <br /><br />3.2 java.util.HashMap<br /><br />HashMap非常类似于Hashtable，它是从Java 1.2平台以后才引入的。HashMap和Hashtable之间有两个主要区别。第一，HashMap是非同步的（为了快速访问），第二，HashMap允许使用null关键字和null值，而Hashtable是不允许的。HashMap的特殊方法（不在Map接口中的）有：<br /><br />public class java.util.HashMap implements Map, Cloneable, java.io.Serializable {<br /><br />     public HashMap(int initialCapacity, float load);   //construct a default HashMap with default capacity and load of 0.75 <br />     public HashMap(int initialCapacity);               //construct a HashMap with passed capacity and default load of 0.75<br />     public HashMap();                                  //construct HashMap with passed capacity and load<br />     public Hashmap(Map);                               //construct HashMap with passed mapping<br /><br />     public Object clone();                             //constructs shallow copy of HashMap (keys/values not copied)<br /><br />     public Object get(Object);                         //get Value from passed in key<br />     public Object put(Object key, Object value);       //insert key/value pair<br /><br />}<br /><br />自Java 1.2平台引入后，HashMap即提供了优于Hashtable的性能。虽然HashMap是非同步的，但可以对它进行同步化。如果在一个多线程的环境下，HashMap被修改了会怎么样？HashMap有一个快速失效（fast-fail）的迭代器。快速失效意味着，当底层集合改变后，迭代器将得到通知，通过抛出ConcurrentModificationException从而导致对下一个元素的提取失败。<br /><br />3.3 java.util.TreeMap<br /><br />TreeMap实现了Map接口，并把元素存储在树中。TreeMap在操作上需要比HashMap更多一些的开销，但是由于树的结构使然，它返回排序的关键字。如果没有按照关键字顺序提取Map的元素的需求，那么HashMap是更实用的结构。TreeMap中实现的不包括在Map接口中的public成员有：<br /><br /><br />public class java.TreeMap implements SortedMap, Cloneable, java.io.Serializable { <br /><br />     public TreeMap();                         //new TreeMap <br />     public TreeMap(Comparator);               //new TreeMap using Comparator <br />     public TreeMap(Map);                      //new TreeMap using Map <br />     public TreeMap(SortedMap);                //new TreeMap using sortedMap <br /><br />     public Comparator comparator(); <br />     public Object firstKey();                 //returns first Key <br />     public Object lastKey();                  //returns last Key <br />     public Object clone();                    //returns shallow copy of TreeMap <br /><br />     public SortedMap headMap(Object);         //returns SortedMap of all elements upto Object <br />     public SortedMap tailMap(Object);         //returns SortedMap of all elements after Object <br />     public SortedMap subMap(Object, Object);  //returns SortedMap of all elements between keys <br /><br />     public Object get(Object);                //get Value from passed in key <br />     public Object put(Object key, Object value);      //insert key/value pair <br />} <br /><br /><br />当你需要以一定顺序存储对象时，TreeMap是非常有用的。例如，电话薄或者字典是使用TreeMap的理想候选。SortedMap是Map的子接口。TreeMap是使用SortedMap接口的唯一实现。<br /><br />4. 实例<br /><br />在下面的部分，我们将展示两个实例，第一个展示了HashMap的使用，第二个则使用了TreeMap。注意代码中的唯一差别仅在一行而已，位于calendar Map实例化时，然而，由于TreeMap和HashMap的存储行为的不同，最终的输出就大不相同了。<br /><br />4.1 HashMap 实例<br /><br /><br /><br /><br />import java.util.*; <br /><br />public class ExampleHashMap { <br /><br />   //calendar Map  <br />   Map calendar = new  HashMap(); <br /><br />   //constructor to add all elements into Map <br />   public ExampleHashMap(String d[], String i[]){ <br />      for (int x=0; x&lt;d.length; x++) <br />         calendar.put(d[x], i[x]); <br />   } <br /><br /><br />   //main method <br />   public static void main(String args[]) { <br /><br />      //Data to be inserted into calendar <br />      String [] dates = {"10/31/01", "01/01/01", "03/05/01", "02/04/01"}; <br />      String [] items = {"Halloween", "New Years", "Birthday", "Anniversary"}; <br /><br />      //create instance of class <br />      ExampleHashMap example = new ExampleHashMap(dates, items); <br /><br />      //print out all key/value pairs in map <br />      System.out.println("map= " + example.calendar); <br /><br />      //retrieve mappings into Set <br />      Set mappings = example.calendar.entrySet(); <br /><br />      System.out.println("object \t\t\tkey\t\tvalue"); <br />      //iterate through mappings and print content <br />      for (Iterator i = mappings.iterator(); i.hasNext();) { <br />         Map.Entry me = (Map.Entry)i.next(); <br />         Object ok = me.getKey(); <br />         Object ov = me.getValue(); <br />         System.out.print(me + "\t"); <br />         System.out.print(ok + "\t"); <br />         System.out.println(ov);  <br />      } <br /><br />   } <br /><br /><br />} <br /><br /><br />- HashMap的输出 (不同的编译器会有不同顺序的输出): <br /><br />/tmp> java ExampleHashMapmap= {01/01/01=New Years, 03/05/01=Birthday, 02/04/01=Anniversary, 10/31/01=Halloween}object                  key             value01/01/01=New Years      01/01/01        New Years03/05/01=Birthday       03/05/01        Birthday02/04/01=Anniversary    02/04/01        Anniversary10/31/01=Halloween      10/31/01        Halloween<br /><br />注意在HashMap对象存储既不是按照年代顺序，也不是按照字母顺序。输出的顺序其实是依赖于你选用了哪种编译器，以及机器的设置。实际上Halloween是第一个“put”到HashMap的，但是却存储在HashMap的最后。<br /><br />4.2 TreeMap 实例<br /><br /><br />import java.util.*; <br /><br />public class ExampleTreeMap { <br /><br />   //calendar Map  <br />   Map calendar = new TreeMap(); <br /><br />   //constructor to add all elements into Map <br />   public ExampleTreeMap(String d[], String i[]){ <br />      for (int x=0; x&lt;d.length; x++) <br />         calendar.put(d[x], i[x]); <br />   } <br /><br /><br />   //main method <br />   public static void main(String args[]) { <br /><br />      //Data to be inserted into calendar <br />      String [] dates = {"10/31/01", "01/01/01", "03/05/01", "02/04/01"}; <br />      String [] items = {"Halloween", "New Years", "Birthday", "Anniversary"}; <br /><br />      //create instance of class <br />      ExampleTreeMap example = new ExampleTreeMap(dates, items); <br /><br />      //print out all key/value pairs in map <br />      System.out.println("map= " + example.calendar); <br /><br />      //retrieve mappings into Set <br />      Set mappings = example.calendar.entrySet(); <br /><br />      System.out.println("object \t\t\tkey\t\tvalue"); <br />      //iterate through mappings and print content <br />      for (Iterator i = mappings.iterator(); i.hasNext();) { <br />         Map.Entry me = (Map.Entry)i.next(); <br />         Object ok = me.getKey(); <br />         Object ov = me.getValue(); <br />         System.out.print(me + "\t"); <br />         System.out.print(ok + "\t"); <br />         System.out.println(ov);  <br />      } <br /><br />   } <br /><br />} <br /><br />- TreeMap的输出: <br /><br />/tmp> java ExampleTreeMapmap= {01/01/01=New Years, 02/04/01=Anniversary, 03/05/01=Birthday, 10/31/01=Halloween}object                  key             value01/01/01=New Years      01/01/01        New Years02/04/01=Anniversary    02/04/01        Anniversary03/05/01=Birthday       03/05/01        Birthday10/31/01=Halloween      10/31/01        Halloween<br /><br /><br />TreeMap的输出比HashMap更加具有可预言性。注意在TreeMap中映射以关键字的字母顺序存储。不同于HashMap的输出，在一个实际的世界日历程序中，TreeMap的输出将更加有用。正如前面提及的，使用TreeMap数据结构的一个缺点是，当你在TreeMap结构中“put”或“remove”元素时，因为需要排序从而需要一些开销，这会影响到程序的性能。（译注：可以先使用HashMap，在需要顺序输出时，通过把HashMap对象作为参数传入，构造一个TreeMap达到高性能同时满足排序的双重目的）。<br /><br />5. 总结<br /><br />作为集合包的一部分，Map接口和其不同实现提供了存储关键字/值对的方便的途径。在考虑应该选用哪个实现时的一般准则是：当元素的顺序很重要时选用TreeMap，当元素不必以特定的顺序进行存储时，使用HashMap。Hashtable的使用不被推荐，因为HashMap提供了所有类似的功能，并且允许得更快。当你需要在多线程环境下使用时，HashMap也可以转换为同步的。
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/155435#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 13 Jan 2008 20:33:22 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/155435</link>
        <guid>http://junjie314.javaeye.com/blog/155435</guid>
      </item>
      <item>
        <title>Java定时器在Web中的应用</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/153885" style="color:red;">http://junjie314.javaeye.com/blog/153885</a>&nbsp;
          发表时间: 2008年01月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在web中,定时器的启动一般随web server的启动而启动,一般有两种方法.<br /><br />方法一：在web.xml里配置一个Servlet，并设置其随web server的启动而启动。然后在该Servlet的init()方法里启动定时器，在destory()方法里销毁定时器。<br />方法二：在web.xml里配置一个Listener,然后在该Listener的初始化方法里启动定时器，在其销毁的方法朝左销毁定时器。<br /><br />在servlet中启动定时器<br /><pre name="code" class="xml">import java.io.IOException;    
import java.util.Timer;    
import javax.servlet.RequestDispatcher;    
import javax.servlet.ServletContext;    
import javax.servlet.ServletException;    
import javax.servlet.http.HttpServlet;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
   
import org.apache.commons.lang.StringUtils;    
   
public class ConvergeDataServlet extends HttpServlet {    
   
    private static final long serialVersionUID = 1L;    
   
    private Timer timer1 = null;    
        
    private Task task1;    
        
    /**   
     * Constructor of the object.   
     */   
    public ConvergeDataServlet() {    
        super();    
    }    
   
    /**   
     * Destruction of the servlet. 
  
     */   
    public void destroy() {    
        super.destroy();     
        if(timer1!=null){    
            timer1.cancel();    
        }    
    }    
   
        
    public void doGet(HttpServletRequest request, HttpServletResponse response)    
            throws ServletException, IOException {    
            
    }    
   
        
    public void doPost(HttpServletRequest request, HttpServletResponse response)    
            throws ServletException, IOException {    
        doGet(request, response);           
    }    
   
    // init方法启动定时器    
    public void init() throws ServletException {    
            
        ServletContext context = getServletContext();    
            
        // (true为用定时间刷新缓存)    
        String startTask = getInitParameter("startTask");    
                    
        // 定时刷新时间(分钟)    
        Long delay = Long.parseLong(getInitParameter("delay"));    
            
        // 启动定时器    
        if(startTask.equals("true")){    
            timer1 = new Timer(true);    
            task1 = new Task(context);    
            timer1.schedule(task1, delay * 60 * 1000, delay * 60 * 1000);    
        }    
    }    
}    
</pre><br />定时执行操作<br /><pre name="code" class="java">/**   
 *    
 * @author callan   
 */   
import java.util.TimerTask;    
   
import javax.servlet.ServletContext;    
   
public class Task extends TimerTask{    
   
    private ServletContext context;    
        
    private static boolean isRunning = true;    
        
    public Task(ServletContext context){    
        this.context = context;    
    }    
        
            
    @Override   
    public void run() {    
        if(isRunning){    
              
        }    
    }    
   
}    
</pre><br />在web.xml配置这个servlet为服务启动时就调用servlet<br /><br />&lt; servlet ><br />     &lt; servlet-name >taskservlet&lt; / servlet-name ><br />    &lt; servlet-class >com.task&lt; /servlet-class ><br />    &lt; init-param ><br />     &lt; param-name >startTask&lt; /param-name ><br />     &lt; param-value >true&lt; /param-value ><br />    &lt; /init-param ><br />    &lt; init-param ><br />     &lt; param-name >intervalTime&lt; /param-name ><br />     &lt; param-value >1&lt; /param-value ><br />    &lt; /init-param ><br />    &lt; load-on-startup >300&lt; /load-on-startup ><br />  &lt; /servlet >
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/153885#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 08 Jan 2008 11:25:34 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/153885</link>
        <guid>http://junjie314.javaeye.com/blog/153885</guid>
      </item>
      <item>
        <title>iBatis小结</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/153763" style="color:red;">http://junjie314.javaeye.com/blog/153763</a>&nbsp;
          发表时间: 2008年01月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;   
&lt;!DOCTYPE sqlMap         
    PUBLIC &quot;-//ibatis.apache.org//DTD SQL Map 2.0//EN&quot;         
    &quot;http://ibatis.apache.org/dtd/sql-map-2.dtd&quot;&gt;   
&lt;sqlMap namespace=&quot;Account&quot;&gt;   
  &lt;typeAlias alias=&quot;Account&quot; type=&quot;test.Account&quot;/&gt;   
  &lt;!--列表查询,返回Account Object的List--&gt;      
  &lt;resultMap id=&quot;AccountResult&quot; class=&quot;Account&quot;&gt;   
    &lt;result property=&quot;id&quot; column=&quot;ID&quot;/&gt;   
    &lt;result property=&quot;firstName&quot; column=&quot;FIRST_NAME&quot;/&gt;   
    &lt;result property=&quot;lastName&quot; column=&quot;LAST_NAME&quot;/&gt;   
    &lt;result property=&quot;emailAddress&quot; column=&quot;EMAIL&quot;/&gt;   
  &lt;/resultMap&gt;     
  &lt;select id=&quot;selectAllAccounts&quot; resultMap=&quot;AccountResult&quot;&gt;   
    select * from ACCOUNT   
  &lt;/select&gt;   
     
  &lt;!--列表查询,返回HashMap的List --&gt;    
  &lt;!--resultMap无需再通过JDBC ResultSetMetaData 来动态获取字段信息，性能有提高--&gt;   
  
  &lt;resultMap id=&quot;mapResult&quot; class=&quot;java.util.HashMap&quot;&gt;   
    &lt;result property=&quot;roleid&quot; column=&quot;ROLEID&quot;/&gt;   
    &lt;result property=&quot;rolename&quot; column=&quot;ROLENAME&quot;/&gt;   
    &lt;result property=&quot;id&quot; column=&quot;ID&quot;/&gt;   
    &lt;result property=&quot;firstName&quot; column=&quot;FIRST_NAME&quot;/&gt;   
    &lt;result property=&quot;lastName&quot; column=&quot;LAST_NAME&quot;/&gt;   
    &lt;result property=&quot;emailAddress&quot; column=&quot;EMAIL&quot;/&gt;   
    &lt;result property=&quot;dt&quot; column=&quot;DT&quot;/&gt;   
  &lt;/resultMap&gt;   
  &lt;select id=&quot;selectAllAccountsWithMap&quot; resultMap=&quot;mapResult&quot;&gt;   
        select B.ROLEID, B.ROLENAME, A.ID, A.FIRST_NAME,A.LAST_NAME,A.EMAIL,A.DT   
        from ACCOUNT A left outer join ROLE B   on A.ROLEID = B.ROLEID   
        ORDER BY A.ID DESC   
  &lt;/select&gt;   
     
&lt;!--动态构造查询条件--&gt;   
&lt;select id=&quot;getUsers&quot; parameterClass=&quot;user&quot; resultMap=&quot;get-user-result&quot;&gt;   
    Select id,name,sex from t_user   
    &lt;dynamic prepend=&quot;WHERE&quot;&gt;   
        &lt;isNotEmpty prepend=&quot;AND&quot; property=&quot;name&quot;&gt;   
            (name like #name#)   
        &lt;/isNotEmpty&gt;   
        &lt;isNotEmpty prepend=&quot;AND&quot; property=&quot;address&quot;&gt;   
            (address like #address#)   
        &lt;/isNotEmpty&gt;   
    &lt;/dynamic&gt;   
&lt;/select&gt;   
&lt;isNotEmpty prepend=&quot;AND&quot; property=&quot;name&quot;&gt;   
    ( name=#name#   
        &lt;isNotEmpty prepend=&quot;AND&quot; property=&quot;address&quot;&gt;   
            address=#address#   
        &lt;/isNotEmpty&gt;   
    )   
&lt;/isNotEmpty&gt;   
&lt;select id=&quot;dynamicGetAccountList&quot; resultMap=&quot;account-result&quot; &gt;   
    select * from ACCOUNT   
    &lt;dynamic prepend=&quot;WHERE&quot;&gt;   
        &lt;isNotNull prepend=&quot;AND&quot; property=&quot;firstName&quot; open=&rdquo;(&ldquo; close=&rdquo;)&rdquo;&gt;   
            ACC_FIRST_NAME = #firstName#   
            &lt;isNotNull prepend=&quot;OR&quot; property=&quot;lastName&quot;&gt;   
                ACC_LAST_NAME = #lastName#   
            &lt;/isNotNull&gt;   
        &lt;/isNotNull&gt;   
        &lt;isNotNull prepend=&quot;AND&quot; property=&quot;emailAddress&quot;&gt;   
            ACC_EMAIL like #emailAddress#   
        &lt;/isNotNull&gt;   
        &lt;isGreaterThan prepend=&quot;AND&quot; property=&quot;id&quot; compareValue=&quot;0&quot;&gt;   
            ACC_ID = #id#   
        &lt;/isGreaterThan&gt;   
    &lt;/dynamic&gt;   
    order by ACC_LAST_NAME   
&lt;/select&gt;   
  
&lt;isParameterPresent&gt; &lt;isNotParameterPresent&gt; &lt;isNull&gt; &lt;isNotNull&gt; &lt;isEmpty&gt; &lt;isNotEmpty&gt;   
&lt;isEqual&gt; &lt;isNotEqual&gt; &lt;isGreaterThan&gt; &lt;isGreaterEqual&gt; &lt;isLessThan&gt; &lt;isLessEqual&gt;   
  
&lt;!-- Sql片段的是用--&gt;   
&lt;sql id=&quot;selectItem_fragment&quot;&gt;   
    FROM items WHERE parentid = 6  
&lt;/sql&gt;   
&lt;select id=&quot;selectItemCount&quot; resultClass=&quot;int&quot;&gt;   
    SELECT COUNT(*) AS total   
    &lt;include refid=&quot;selectItem_fragment&quot;/&gt;   
&lt;/select&gt;   
&lt;select id=&quot;selectItems&quot; resultClass=&quot;Item&quot;&gt;   
    SELECT id, name   
    &lt;include refid=&quot;selectItem_fragment&quot;/&gt;   
&lt;/select&gt;   
  
&lt;!--缓存--&gt;   
&lt;cacheModel id=&quot;product-cache&quot; type=&quot;LRU&quot;&gt;   
    &lt;flushInterval hours=&quot;24&quot;/&gt;   
    &lt;flushOnExecute statement=&quot;insertProduct&quot;/&gt;   
    &lt;flushOnExecute statement=&quot;updateProduct&quot;/&gt;   
    &lt;flushOnExecute statement=&quot;deleteProduct&quot;/&gt;   
    &lt;property name=&rdquo;size&rdquo; value=&rdquo;1000&rdquo; /&gt;   
&lt;/cacheModel&gt;   
&lt;select id=&rdquo;getProductList&rdquo; parameterClass=&rdquo;int&rdquo; cacheModel=&rdquo;product-cache&rdquo;&gt;   
    select * from PRODUCT where PRD_CAT_ID = #value#   
&lt;/select&gt;   
  
&lt;!&mdash;对XML支持 --&gt;   
&lt;select id=&quot;getPerson&quot; parameterClass=&rdquo;int&rdquo; resultClass=&quot;xml&quot; xmlResultName=&rdquo;person&rdquo;&gt;   
    SELECT   
    PER_ID as id,   
    PER_FIRST_NAME as firstName,   
    PER_LAST_NAME as lastName,   
    PER_BIRTH_DATE as birthDate,   
    PER_WEIGHT_KG as weightInKilograms,   
    PER_HEIGHT_M as heightInMeters   
    FROM PERSON   
    WHERE PER_ID = #value#   
&lt;/select&gt;   
&lt;person&gt;   
    &lt;id&gt;1&lt;/id&gt;   
    &lt;firstName&gt;Clinton&lt;/firstName&gt;   
    &lt;lastName&gt;Begin&lt;/lastName&gt;   
    &lt;birthDate&gt;1900-01-01&lt;/birthDate&gt;   
    &lt;weightInKilograms&gt;89&lt;/weightInKilograms&gt;   
    &lt;heightInMeters&gt;1.77&lt;/heightInMeters&gt;   
&lt;/person&gt;   
  
&lt;!&mdash;字符串替换   
select * from $tableName$   
Important Note 1: This support will only substitute Strings, so it is not appropriate for complex data types like Date or Timestamp.   
Important Note 2: If you use this support to alter a table name, or a column list, in an SQL select statement,then you should always specify remapResults=&ldquo;true&rdquo;   
--&gt;.   
  
&lt;!&mdash;关联查询方式，有1/N问题--&gt;   
&lt;sqlMap namespace=&quot;User&quot;&gt;   
    &lt;typeAlias alias=&quot;user&quot; type=&quot;com.ibatis.sample.User&quot;/&gt;   
    &lt;typeAlias alias=&quot;address&quot; type=&quot;com.ibatis.sample.Address&quot;/&gt;   
    &lt;resultMap id=&quot;get-user-result&quot; class=&quot;user&quot;&gt;   
        &lt;result property=&quot;id&quot; column=&quot;id&quot;/&gt;   
        &lt;result property=&quot;name&quot; column=&quot;name&quot;/&gt;   
        &lt;result property=&quot;sex&quot; column=&quot;sex&quot;/&gt;   
        &lt;result property=&quot;addresses&quot; column=&quot;id&quot; select=&quot;User.getAddressByUserId&quot;/&gt;   
    &lt;/resultMap&gt;   
    &lt;select id=&quot;getUsers&quot;    parameterClass=&quot;java.lang.String&quot; resultMap=&quot;get-user-result&quot;&gt;   
        &lt;![CDATA[Select id,name,sex from t_user where id = #id#]]&gt;   
    &lt;/select&gt;   
    &lt;select id=&quot;getAddressByUserId&quot;  parameterClass=&quot;int&quot; resultClass=&quot;address&quot;&gt;   
        &lt;![CDATA[select address,zipcode from t_address where user_id = #userid# ]]&gt;   
    &lt;/select&gt;   
&lt;/sqlMap&gt;   
&lt;resultMap id=&quot;get-user-result&quot; class=&quot;user&quot;&gt;   
    &lt;result property=&quot;id&quot; column=&quot;id&quot;/&gt;   
    &lt;result property=&quot;name&quot; column=&quot;name&quot;/&gt;   
    &lt;result property=&quot;sex&quot; column=&quot;sex&quot;/&gt;   
    &lt;result property=&quot;address&quot; column=&quot;t_address.address&quot;/&gt;   
    &lt;result property=&quot;zipCode&quot; column=&quot;t_address.zipcode&quot;/&gt;   
&lt;/resultMap&gt;   
&lt;select id=&quot;getUsers&quot; parameterClass=&quot;java.lang.String&quot; resultMap=&quot;get-user-result&quot;&gt;   
    &lt;![CDATA[select* from t_user,t_address where t_user.id=t_address.user_id]]&gt;   
&lt;/select&gt;   
保证User 类中包含address和zipCode两个String型属性。   
  
&lt;!&mdash;关联查询，无1/N问题--&gt;   
  &lt;resultMap id=&quot;AccountResultWithRole&quot; class=&quot;Account&quot; groupBy=&quot;id&quot;&gt;   
    &lt;result property=&quot;id&quot; column=&quot;ID&quot;/&gt;   
    &lt;result property=&quot;firstName&quot; column=&quot;FIRST_NAME&quot;/&gt;   
    &lt;result property=&quot;lastName&quot; column=&quot;LAST_NAME&quot;/&gt;   
    &lt;result property=&quot;emailAddress&quot; column=&quot;EMAIL&quot;/&gt;       
    &lt;result property=&quot;role&quot; resultMap=&quot;Account.roleResult&quot;/&gt;   
  &lt;/resultMap&gt;   
  &lt;resultMap id=&quot;roleResult&quot; class=&quot;test.Role&quot;&gt;   
    &lt;result property=&quot;roleid&quot; column=&quot;ROLEID&quot;/&gt;   
    &lt;result property=&quot;rolename&quot; column=&quot;ROLENAME&quot;/&gt;   
  &lt;/resultMap&gt;   
  &lt;select id=&quot;selectAccountByIdWithRole&quot; parameterClass=&quot;int&quot; resultMap=&quot;AccountResultWithRole&quot;&gt;   
        select B.ROLEID, B.ROLENAME, A.ID, A.FIRST_NAME,A.LAST_NAME,A.EMAIL from ACCOUNT A left outer join ROLE B on A.ROLEID = B.ROLEID where A.ID = #id#   
  &lt;/select&gt;   
     
  &lt;!--查询--&gt;      
  &lt;select id=&quot;selectAccountById&quot; parameterClass=&quot;int&quot; resultClass=&quot;Account&quot;&gt;   
    select ID as id,FIRST_NAME as firstName,LAST_NAME as lastName,       EMAIL as emailAddress from ACCOUNT where ID = #id#   
  &lt;/select&gt;   
     
  &lt;!--新增--&gt;        
  &lt;insert id=&quot;insertAccount&quot; parameterClass=&quot;Account&quot;&gt;   
    insert into ACCOUNT (FIRST_NAME,LAST_NAME,EMAIL,PID,DT)     
    values (#firstName:VARCHAR#, #lastName:VARCHAR#, #emailAddress:VARCHAR#,#pid:INTEGER:0#,#dt:TIME#)   
    &lt;selectKey resultClass=&quot;int&quot; type=&quot;post&quot; keyProperty=&quot;id&quot;&gt;   
        SELECT @@IDENTITY AS ID   
    &lt;/selectKey&gt;       
  &lt;/insert&gt;   
     
  &lt;!--更新--&gt;      
  &lt;update id=&quot;updateAccount&quot; parameterClass=&quot;Account&quot;&gt;   
    update ACCOUNT set   
      FIRST_NAME = #firstName:VARCHAR#,   
      LAST_NAME = #lastName:VARCHAR#,   
      EMAIL = #emailAddress:VARCHAR#   
    where   
      ID = #id#   
  &lt;/update&gt;   
  
  &lt;!--删除--&gt;   
  &lt;delete id=&quot;deleteAccountById&quot; parameterClass=&quot;int&quot;&gt;   
    delete from ACCOUNT where ID = #id#   
  &lt;/delete&gt;   
     
  &lt;!--存储过程，如果没有返回列表，procTest的resultMap可以省略--&gt;    
  &lt;parameterMap id=&quot;procParamMap&quot; class=&quot;java.util.HashMap&quot; &gt;   
    &lt;parameter property=&quot;id&quot; jdbcType=&quot;INTEGER&quot; javaType=&quot;java.lang.Integer&quot; mode=&quot;IN&quot;/&gt;   
    &lt;parameter property=&quot;outid&quot; jdbcType=&quot;INTEGER&quot; javaType=&quot;java.lang.Integer&quot; mode=&quot;OUT&quot;/&gt;   
    &lt;parameter property=&quot;errMsg&quot; jdbcType=&quot;VARCHAR&quot; javaType=&quot;java.lang.String&quot; mode=&quot;OUT&quot;/&gt;   
  &lt;/parameterMap&gt;   
  &lt;resultMap id=&quot;procResultMap&quot; class=&quot;java.util.HashMap&quot; &gt;   
    &lt;result property=&quot;a&quot; column=&quot;AAA&quot;/&gt;   
    &lt;result property=&quot;b&quot; column=&quot;BBB&quot;/&gt;   
    &lt;result property=&quot;c&quot; column=&quot;CCC&quot;/&gt;       
  &lt;/resultMap&gt;     
  &lt;procedure id=&quot;procTest&quot; parameterMap=&quot;procParamMap&quot; resultMap=&quot;procResultMap&quot;&gt;   
    {call test_sp_1 (?,?,?)}   
  &lt;/procedure&gt;   
&lt;/sqlMap&gt;  
</pre>&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/153763#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 Jan 2008 21:01:45 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/153763</link>
        <guid>http://junjie314.javaeye.com/blog/153763</guid>
      </item>
      <item>
        <title>JS验证电话号码</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/99530" style="color:red;">http://junjie314.javaeye.com/blog/99530</a>&nbsp;
          发表时间: 2007年07月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span><span class="keyword">function</span><span>&nbsp;Checkreg() &nbsp;&nbsp;</span></span></li>
    <li class=""><span>{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">//验证电话号码手机号码，包含153，159号段 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(document.form.phone.value==</span><span class="string">&quot;&quot;</span><span>&nbsp;&amp;&amp;&nbsp;document.form.UserMobile.value==</span><span class="string">&quot;&quot;</span><span>){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>alert(</span><span class="string">&quot;电话号码和手机号码至少选填一个阿！&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>document.form.phone.focus(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(document.form.phone.value&nbsp;!=&nbsp;</span><span class="string">&quot;&quot;</span><span>){ &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">var</span><span>&nbsp;phone=document.form.phone.value; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">var</span><span>&nbsp;p1&nbsp;=&nbsp;/^(([0\+]\d{2,3}-)?(0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">var</span><span>&nbsp;me&nbsp;=&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(p1.test(phone))me=</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!me){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>document.form.phone.value=</span><span class="string">''</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span>alert('对不起，您输入的电话号码有错误。区号和电话号码之间请用-分割'); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>document.form.phone.focus(); &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(document.form.UserMobile.value&nbsp;!=&nbsp;</span><span class="string">&quot;&quot;</span><span>){ &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">var</span><span>&nbsp;mobile=document.form.UserMobile.value; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">var</span><span>&nbsp;reg0&nbsp;=&nbsp;/^13\d{5,9}$/; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">var</span><span>&nbsp;reg1&nbsp;=&nbsp;/^153\d{4,8}$/; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">var</span><span>&nbsp;reg2&nbsp;=&nbsp;/^159\d{4,8}$/; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">var</span><span>&nbsp;reg3&nbsp;=&nbsp;/^0\d{10,11}$/; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">var</span><span>&nbsp;my&nbsp;=&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(reg0.test(mobile))my=</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(reg1.test(mobile))my=</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(reg2.test(mobile))my=</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(reg3.test(mobile))my=</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!my){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>document.form.UserMobile.value=</span><span class="string">''</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span>alert('对不起，您输入的手机或小灵通号码有错误。'); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>document.form.UserMobile.focus(); &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>说明 &nbsp;&nbsp;</span></li>
    <li class=""><span>test方法检查在字符串中是否存在一个模式，如果存在则返回&nbsp;</span><span class="keyword">true</span><span>，否则就返回&nbsp;</span><span class="keyword">false</span><span>。 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>正则表达式部分： &nbsp;&nbsp;</span></li>
    <li class="alt"><span>\d&nbsp;代表一个数字 &nbsp;&nbsp;</span></li>
    <li class=""><span>{7,8}&nbsp;代表7－8位数字（表示电话号码） &nbsp;&nbsp;</span></li>
    <li class="alt"><span>{3,}&nbsp;代表分机号码 &nbsp;&nbsp;</span></li>
    <li class=""><span>d{2,3}&nbsp;代表区号 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>\+]\d{2,3}&nbsp;代表国际区号 &nbsp;&nbsp;</span></li>
    <li class=""><span>^13\d{5,9}$/&nbsp;</span><span class="comment">//130?139。至少5位，最多9位 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>/^153\d{4,8}$/&nbsp;</span><span class="comment">//联通153。至少4位，最多8位 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>/^159\d{4,8}$/&nbsp;</span><span class="comment">//移动159。至少4位，最多8位&nbsp;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/99530#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 10 Jul 2007 00:42:05 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/99530</link>
        <guid>http://junjie314.javaeye.com/blog/99530</guid>
      </item>
      <item>
        <title>程序员数据结构笔记(三)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/91709" style="color:red;">http://junjie314.javaeye.com/blog/91709</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="FONT-SIZE: 10pt">想想下面这个算法：求链表所有数据的平均值(我也没试过)，不许偷懒，用递归试试哦! <br />
　　递归程序员<a href="http://www.stsj86.com/" class="kk" id="studaexam785" target="_blank">考试</a>题目类型：1)就是链表的某些操作(比如上面的求平均值) <br />
　　　　　　　　　　　　　　2)二叉树(遍历等)&nbsp; <br />
　　例2.判断数组元素是否递增 <br />
　　　　　int&nbsp;jidge(int&nbsp;a[],int&nbsp;n)&nbsp;{ <br />
　　　　　　if(n==1)&nbsp;return&nbsp;1; <br />
　　　　　　else <br />
　　　　　　　if(a[0]&gt;a[1])&nbsp;return&nbsp;0; <br />
　　　　　　　else&nbsp;return&nbsp;jidge(a+1,n-1); <br />
　　　　　} <br />
　　例3.求二叉树的高度(根据二叉树的递归性质:(左子树)根(右子树)) <br />
　　　　　int&nbsp;depth(nodetype&nbsp;*root)&nbsp;{ <br />
　　　　　　if(root==NULL)&nbsp; <br />
　　　　　　　return&nbsp;0; <br />
　　　　　　else&nbsp;{ <br />
　　　　　　　h1=depth(root-&gt;lch); <br />
　　　　　　　h2=depth(root-&gt;rch); <br />
　　　　　　　return&nbsp;max(h1,h2)+1; <br />
　　　　　　} <br />
　　　　　&nbsp;} <br />
　　自己想想求二叉树结点个数(与上例类似) <br />
　　例4.已知中序遍历和后序遍历,求二叉树. <br />
　　　设一二叉树的: <br />
　　　中序&nbsp;S:E&nbsp;D&nbsp;F&nbsp;B&nbsp;A&nbsp;G&nbsp;J&nbsp;H&nbsp;C&nbsp;I <br />
　　　　　　^start1&nbsp;^j&nbsp;^end1 <br />
　　　后序&nbsp;T:E&nbsp;F&nbsp;D&nbsp;B&nbsp;J&nbsp;H&nbsp;G&nbsp;I&nbsp;C&nbsp;A <br />
　　　　　　^start2&nbsp;^end2 <br />
　　　　node&nbsp;*create(char&nbsp;*s,char&nbsp;*t,&nbsp;int&nbsp;start1,int&nbsp;start2,int&nbsp;end1,int&nbsp;end2)&nbsp; <br />
　　　　{&nbsp;if&nbsp;(start1&gt;end1)&nbsp;return&nbsp;NULL;&nbsp;//回归条件 <br />
　　　　　root=(node&nbsp;*)malloc(sizeof(node)); <br />
　　　　　root-&gt;data=t[end2]; <br />
　　　　　找到S中T[end2]的位置为&nbsp;j <br />
　　　　　root-&gt;lch=create(S,T,s1,j-1,start1,j+start2-start1-1); <br />
　　　　　root-&gt;rch=create(S,T,j+1,end1,j+start2-start1,end2-1); <br />
　　　　　return&nbsp;root; <br />
　　　　} <br />
　　例5.组合问题 <br />
　　　n&nbsp;个数:&nbsp;(1,2,3,4,&hellip;n)求从中取r个数的所有组合. <br />
　　　设n=5,r=3; <br />
　　　递归思想：先固定一位&nbsp;5&nbsp;(从另四个数当中选二个) <br />
　　　　　　　　　　　　　&nbsp;5,4&nbsp;(从另三个数当中选一个) <br />
　　　　　　　　　　　　　&nbsp;5,4,3&nbsp;(从另二个数当中选零个) <br />
　　　即：n-2个数中取r-2个数的所有组合 <br />
　　　　　&hellip; <br />
　　程序: <br />
　　　void&nbsp;combire(int&nbsp;n,int&nbsp;r)&nbsp;{ <br />
　　　　for(k=n;k&gt;=n+r-1;k--)&nbsp;{ <br />
　　　　　a[r]=k; <br />
　　　　　if(r==0)&nbsp;打印a数组(表示找到一个解); <br />
　　　　　else&nbsp;combire(n-1,r-1); <br />
　　　　} <br />
　　　} <br />
回溯法: <br />
　　回溯跟递归都是程序员<a href="http://www.stsj86.com/" class="kk" id="studaexam785" target="_blank">考试</a>里常出现的问题,大家必须掌握! <br />
　　回溯法的有关概念: <br />
　　1)&nbsp;解答树:叶子结点可能是解,对结点进行后序遍历. <br />
　　2)&nbsp;搜索与回溯 <br />
　　五个数中任选三个的解答树(解肯定有三层,至叶子结点):&nbsp; <br />
　　　　　　　　　　　　　　　ROOT&nbsp;虚根 <br />
　　　　　　　　/　　　　　　/　　　&nbsp;|　　　　 <br />
　　　　　　　&nbsp;1　　　　　&nbsp;2　　　　&nbsp;3　　4　　&nbsp;5 <br />
　　　　/&nbsp;　|　&nbsp;|　&nbsp;　　/&nbsp;|&nbsp;&nbsp;　　&nbsp;/　　| <br />
　　　&nbsp;2　　3　&nbsp;4　　5　3　4　5　　4　5　&nbsp;5 <br />
　　　/|&nbsp;　/　|　&nbsp;/　|　| <br />
　　&nbsp;3&nbsp;4&nbsp;5&nbsp;4　5&nbsp;5　4　5&nbsp;5　5 <br />
　　回溯算法实现中的技巧:栈 <br />
　　要搞清回溯算法，先举一个(中序遍历二叉树的非递归算法)来说明栈在非递归中所起的作用。 <br />
　　　　　&nbsp;A&nbsp;过程：push()-&gt;push()-&gt;push()-&gt;push()栈内结果:ABDE(E为叶子,结束进栈) <br />
　　　　　/&nbsp;　　　pop()　　　ABD(E无右孩子,出栈) <br />
　　　　&nbsp;B　&nbsp;C　　&nbsp;pop()　　　AB(D无右孩子,出栈)&nbsp; <br />
　　　　/　　　　&nbsp;pop()　　　A(B有右孩子,右孩子进栈) <br />
　　　&nbsp;D　F&nbsp;　　　　.　　　　　&nbsp;. <br />
　　　/　/　　　　&nbsp;.&nbsp;　　　　　. <br />
　　&nbsp;E　G　H　　　　.&nbsp;　　　　　. <br />
　　/　　　　　　　&nbsp;.　　　　　&nbsp;. <br />
　&nbsp;I　　　　　　　&nbsp;最后结果：&nbsp;EDBGFIHAC <br />
　　简单算法: <br />
　　　　&hellip; <br />
　　　if(r!=NULL)&nbsp;//树不空 <br />
　　　{&nbsp;while(r!=NULL)&nbsp; <br />
　　　　{&nbsp;push(s,r); <br />
　　　　　r=r-&gt;lch;　　　//一直向左孩子前进 <br />
　　　　} <br />
　　　　while(!empty(s))&nbsp;//&nbsp;栈非空,出栈 <br />
　　　　{&nbsp;p=pop(s); <br />
　　　　　printf(p-&gt;data); <br />
　　　　　p=p-&gt;rch;　　　//向右孩子前进 <br />
　　　　　while(p!=NULL) <br />
　　　　　{&nbsp;push(s,p); <br />
　　　　　　p=p-&gt;lch;&nbsp;//右孩子进栈 <br />
　　　　　} <br />
　　　　}&nbsp; <br />
　　　}　//这就是传说中的回溯,嘻嘻&hellip;&hellip;没吓着你吧 <br />
5选3问题算法: <br />
　　思想:&nbsp;进栈:搜索 <br />
　　出栈:回溯 <br />
　　边建树(进栈)边遍历(出栈) <br />
　　基本流程:&nbsp; <br />
　　太复杂了,再说我不太喜欢用WORD画图（有损形象），以后再整理! <br />
　　程序:&nbsp;n=5;r=3 <br />
　　　　　&hellip;&hellip; <br />
　　　　　init(s)　　//初始化栈 <br />
　　　　　push(s,1)　//根进栈 <br />
　　　　　while(s.top&lt;r-1)&amp;&amp;(s.data[s.top]!=n)&nbsp;//有孩子 <br />
　　　　　　push(s,s.data[s.top]+1);&nbsp;//孩子入栈 <br />
　　　　　while(!empty(s)) <br />
　　　　　{&nbsp;if(s.top=r-1) <br />
　　　　　　判断该&quot;解&quot;是否为解. <br />
　　　　　　x=pop(s);&nbsp;//保留x,判断是否为最大值n,如果是n,则出栈 <br />
　　　　　　while(x==n) <br />
　　　　　　x=pop(s); <br />
　　　　　　push(s,x+1); <br />
　　　　　　while(s.top&lt;r-1)&amp;&amp;(s.data[s.top]!=n) <br />
　　　　　　push(s,s.data[s.top]+1); <br />
　　　　　} <br />
　　背包问题:&nbsp;TW=20&nbsp;,&nbsp;w[5]={6,10,7,5,8}&nbsp; <br />
　　解的条件:1)&nbsp;该解答树的叶子结点 <br />
　　2)&nbsp;重量最大 <br />
　　解答树如下：　　　ROOT <br />
　　　　　　　/&nbsp;|&nbsp;|&nbsp;|&nbsp; <br />
　　　　　　　　　&nbsp;6&nbsp;10　　&nbsp;7　　　5　&nbsp;8 <br />
　　　　　　　　/&nbsp;|&nbsp;|&nbsp;　&nbsp;/&nbsp;|&nbsp;　&nbsp;/&nbsp;　|&nbsp; <br />
　　　　　　　&nbsp;10&nbsp;7&nbsp;5　8&nbsp;7　5　8&nbsp;5　&nbsp;8&nbsp;8 <br />
　　　　　　　　　|&nbsp;|　　　　　　|&nbsp; <br />
　　　　　　　　　5&nbsp;8　　　　　　8 <br />
</span>
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/91709#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 23:22:39 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/91709</link>
        <guid>http://junjie314.javaeye.com/blog/91709</guid>
      </item>
      <item>
        <title>程序员数据结构笔记(二)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/91708" style="color:red;">http://junjie314.javaeye.com/blog/91708</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1）&nbsp;递推&nbsp;6!=&gt;5!=&gt;4!=&gt;3!=&gt;2!=&gt;1!=&gt;0! <br />
　　2）&nbsp;回归&nbsp;720&lt;=120&lt;=24&lt;=6&nbsp;&lt;=2&nbsp;&lt;=1&nbsp;&lt;=0&nbsp; <br />
　　递归<a href="http://www.studa.com/" class="kk" id="studaexam253" target="_blank">工作</a>栈实现递归的机制。 <br />
　　2、有关算法： <br />
　　1）&nbsp;顺序，链表结构下的出栈，入栈 <br />
　　2）&nbsp;循環，队列的入队列，出队列。 <br />
　　3）&nbsp;链队列的入队列，出队列。 <br />
　　4）&nbsp;表达式计算：后缀表达式&nbsp;35+6/4368/+*-&nbsp; <br />
　　　　　　　　　　中缀表达式&nbsp;（3+5）/6-4*（3+6/8）&nbsp; <br />
　　由于中缀比较难处理，计算机内一般先将中缀转换为后缀。 <br />
　　运算：碰到操作数，不运算，碰到操符，运算其前两个操作数。 <br />
　　　中缀=&gt;后缀 <br />
　　5)&nbsp;迷宫问题 <br />
　　6)&nbsp;线性链表的递归算法&nbsp;一个链表=一个结点+一个链表 <br />
　　int&nbsp;fuction(NODE&nbsp;*p)&nbsp;{ <br />
　　　if(p==NULL)&nbsp;return&nbsp;0; <br />
　　　else&nbsp;return(function(p-&gt;next)); <br />
　　} <br />
　　树与二叉树 <br />
　　一、&nbsp;知识点: <br />
　　1.&nbsp;树的定义:&nbsp;data_struct(D,R); <br />
　　其中:D中有一个根,把D和出度去掉,可以分成M个部分. <br />
　　D1,D2,D3,D4,D5&hellip;DM <br />
　　R1,R2,R3,R4,R5&hellip;RM <br />
　　而子树Ri形成树. <br />
　　1)&nbsp;递归定义&nbsp;高度 <br />
　　2)&nbsp;结点个数=1&nbsp; <br />
　　&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;O&nbsp;&nbsp;&nbsp;&nbsp;--0 <br />
&nbsp; <br />
&nbsp;O&nbsp;&nbsp;&nbsp;&nbsp;O&nbsp;&nbsp;--1 <br />
&nbsp; <br />
O&nbsp;&nbsp;O&nbsp;&nbsp;O&nbsp;&nbsp;O&nbsp;--2 <br />
&nbsp;此树的高度为2 <br />
　　2.二叉树定义:&nbsp;&nbsp;&nbsp; <br />
　　结点个数&gt;=0&nbsp;. <br />
　　3.&nbsp;术语:左右孩子,双亲,子树,度,高度等概念. <br />
　　4.&nbsp;二叉树的性质 <br />
　　●层次为I的二叉树&nbsp;I层结点&nbsp;2I&nbsp;个 <br />
　　●高度为H的二叉树结点&nbsp;2H+1-1个 <br />
　　●H(点)=E(边)+1 <br />
　　●个数为N的完全二叉树高度为|_LOG2n_| <br />
　　●完全二叉树结点编号:从上到下,从左到右.&nbsp; <br />
i结点的双亲:&nbsp;|_i/2_|&nbsp;|_i-1/2_|&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp; <br />
i结点的左孩子:&nbsp;2i&nbsp;2i+1&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp; <br />
i结点的右孩子:&nbsp;2i+1&nbsp;2i+2&nbsp;4&nbsp;&nbsp;5&nbsp;&nbsp;6&nbsp;&nbsp;7&nbsp; <br />
(根)&nbsp;1为起点&nbsp;0为起点&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
　　二叉树的存储结构: <br />
　　　　1)&nbsp;扩展成为完全二叉树,以一维数组存储。&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp; <br />
&nbsp;D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;&nbsp;F&nbsp; <br />
G&nbsp;&nbsp;H&nbsp;&nbsp;&nbsp;&nbsp;I&nbsp;&nbsp;&nbsp;&nbsp; <br />
数组下标&nbsp;0&nbsp;1&nbsp;2&nbsp;3&nbsp;4&nbsp;5&nbsp;6&nbsp;7&nbsp;8&nbsp;9&nbsp;10&nbsp;11&nbsp;12&nbsp; <br />
元素&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;H&nbsp;　&nbsp;　&nbsp;　&nbsp;　&nbsp;I&nbsp; <br />
　　　　2)&nbsp;双亲表示法&nbsp;&nbsp; <br />
数组下标&nbsp;0&nbsp;1&nbsp;2&nbsp;3&nbsp;4&nbsp;5&nbsp;6&nbsp;7&nbsp;8&nbsp; <br />
元素&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;H&nbsp;I&nbsp; <br />
双亲&nbsp;-1&nbsp;0&nbsp;0&nbsp;1&nbsp;2&nbsp;2&nbsp;3&nbsp;3&nbsp;4&nbsp; <br />
　　　　3)&nbsp;双亲孩子表示法&nbsp; <br />
数组下标&nbsp;0&nbsp;1&nbsp;2&nbsp;3&nbsp;4&nbsp;5&nbsp;&hellip;&nbsp; <br />
元素&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;&hellip;&nbsp; <br />
双亲&nbsp;-1&nbsp;0&nbsp;0&nbsp;1&nbsp;2&nbsp;2&nbsp;&hellip;&nbsp; <br />
左子&nbsp;1&nbsp;3&nbsp;4&nbsp;　&nbsp;　&nbsp;　&nbsp;&hellip;&nbsp; <br />
右子&nbsp;2&nbsp;-1&nbsp;5&nbsp;　&nbsp;　&nbsp;　&nbsp;&hellip;&nbsp; <br />
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/91708#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 23:21:58 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/91708</link>
        <guid>http://junjie314.javaeye.com/blog/91708</guid>
      </item>
      <item>
        <title>程序员数据结构笔记(一)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/91707" style="color:red;">http://junjie314.javaeye.com/blog/91707</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.数据结构中对象的定义,存储的表示及操作的实现. <br />
　　2.线性:线性表、栈、队列、数组、字符串（广义表不考） <br />
　　　树：二叉树 <br />
　　　集合：查找，排序 <br />
　　　图(不考) <br />
能力： <br />
　　分析，解决问题的能力 <br />
过程： <br />
　　●&nbsp;确定问题的数据。 <br />
　　●&nbsp;确定数据间的关系。 <br />
　　●&nbsp;确定存储结构（顺序－数组、链表－指针） <br />
　　●&nbsp;确定算法 <br />
　　●&nbsp;编程 <br />
　　●&nbsp;算法评价（<a href="http://www.studa.com/" class="kk" id="studaexam681" target="_blank">时间</a>和空间复杂度，主要考<a href="http://www.studa.com/" class="kk" id="studaexam681" target="_blank">时间</a>复杂度） <br />
一、数组 <br />
　　1、存放于一个连续的空间 <br />
　　2、一维～多维数组的地址计算方式 <br />
　　已知data[0][0]的内存地址，且已知一个元素所占内存空间s求data[i][j]在内存中的地址。 <br />
　　　公式：（add+(i*12+j)*S)(假设此数组为data[10][12]) <br />
　　注意：起始地址不是data[0][0]时候的情况。起始地址为data[-3][8]和情况； <br />
　　3、顺序表的定义 <br />
　　　存储表示及相关操作 <br />
　　4、顺序表操作中时间复杂度估计 <br />
　　5、字符串的定义（字符串就是线性表），存储表示 <br />
　　　模式匹配算法（简单和KMP（不考）） <br />
　　6、特殊矩阵：存储<a href="http://www.stsj86.com/" class="kk" id="studaexam337" target="_blank">方法</a>（压缩存储（按行，按列）） <br />
　　　三对角：存储于一维数组 <br />
　　　三对角问题：已知Aij能求出在一维数组中的下标k;已知下标k求Aij。 <br />
　　7、稀疏矩阵：定义，存储方式：三元组表、十字链表（属于图部分，不考）&nbsp; <br />
　　算法 <br />
　　●&nbsp;数组中元素的原地逆置；&nbsp;对换 <br />
　　●&nbsp;在顺序表中搜索值为X的元素； <br />
　　●&nbsp;在有序表中搜索值为X的元素；（折半查找） <br />
　　●&nbsp;在顺序表中的第i个位置插入元素X； <br />
　　●&nbsp;在顺序表中的第i个位置删除元素X； <br />
　　●&nbsp;两个有序表的合并；算法？ <br />
　　线性表数据结构定义： <br />
　　　Typedef&nbsp;struct&nbsp;{ <br />
　　　　int&nbsp;data[max_size]; <br />
　　　　int&nbsp;len; <br />
　　　}linear_list; <br />
　　●&nbsp;模式匹配 <br />
　　●&nbsp;字符串相加 <br />
　　●&nbsp;求子串 <br />
　　●&nbsp;（i,j）&lt;=&gt;K&nbsp;注意：不同矩阵所用的公式不同； <br />
　　●&nbsp;稀疏矩阵的转置（两种方式，后种为妙） <br />
　　●&nbsp;和数组有关的算法&nbsp; <br />
-------------------------------------------------------------------------------- <br />
　　例程：求两个长整数之和。 <br />
　　a=13056952168 <br />
　　b=87081299 <br />
　　数组: <br />
　　a[]:1&nbsp;3&nbsp;0&nbsp;5&nbsp;6&nbsp;9&nbsp;5&nbsp;2&nbsp;1&nbsp;6&nbsp;8 <br />
　　b[]:8&nbsp;7&nbsp;0&nbsp;8&nbsp;1&nbsp;2&nbsp;9&nbsp;9&nbsp; <br />
由于以上的结构不够直观(一般越是直观越容易解决)&nbsp;将其改为: <br />
　　a[]:11　8&nbsp;6&nbsp;1&nbsp;2&nbsp;5&nbsp;9&nbsp;6&nbsp;5&nbsp;0&nbsp;3&nbsp;1&nbsp;a[0]=11(位数) <br />
　　b[]:&nbsp;8　9&nbsp;9&nbsp;2&nbsp;1&nbsp;8&nbsp;0&nbsp;7&nbsp;8&nbsp;0&nbsp;0&nbsp;0&nbsp;b[0]=8 <br />
　　c进位　0&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp;1&nbsp;1&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp; <br />
　　c[]:11　7&nbsp;6&nbsp;4&nbsp;3&nbsp;3&nbsp;0&nbsp;4&nbsp;4&nbsp;2&nbsp;3&nbsp;1&nbsp;c[0]的值(C位数)由c[max_s+1]决定! <br />
　　注意:在求C前应该将C(max_s+1)位赋0.否则为随机数;&nbsp;较小的整数高位赋0. <br />
　　算法:已知a,b两个长整数,结果:c=a+b; <br />
　　总共相加次数:&nbsp;max_s=max(a[],b[]) <br />
　　程序: <br />
　　for(i=1;i&lt;=max_s;i++)&nbsp;{ <br />
　　　k=a[i]+b[i]+c[i]; <br />
　　　c[i]=k; <br />
　　　c[i+1]=k/10; <br />
　　} <br />
　　<font color="#ffffff" id="rgsdfm16972">转贴于 学生大考试站 http://www.stsj86.com</font><!--分页-->求c位数: <br />
　　if(c[max_s+1]==0) <br />
　　　c[0]=max_s; <br />
　　else <br />
　　　c[0]=max_s+1; <br />
　　以下代码是我编的(毕竟是初学者.不太简洁大家不要见怪!): <br />
　　/*两长整数相加*/ <br />
　　&nbsp;#include<stdio.h></stdio.h> <br />
　　&nbsp;#include<string.h></string.h> <br />
　　#define&nbsp;PRIN&nbsp;printf(&quot; &quot;); <br />
　　int&nbsp;flag=0;&nbsp;/*a[0]&gt;b[0]?1:0*/ <br />
　　/*&nbsp;max(a[],b[])&nbsp;{}*/ <br />
　　change(char&nbsp;da[],char&nbsp;db[],int&nbsp;a[],int&nbsp;b[],int&nbsp;c[])&nbsp;{ <br />
　　　int&nbsp;i; <br />
　　　if(a[0]&gt;b[0])&nbsp;{ <br />
　　　　for(i=1;i&lt;=a[0];a[i]=da[a[0]-i]-&rsquo;0&rsquo;,i++);&nbsp;/*a[0]-&rsquo;0&rsquo;&nbsp;so&nbsp;good!*/ <br />
　　　　for(i=1;i&lt;=b[0];b[i]=db[b[0]-i]-&rsquo;0&rsquo;,i++); <br />
　　　　for(i=b[0]+1;i&lt;=a[0];b[i]=0,i++); <br />
　　　　for(i=1;i&lt;=a[0]+1;c[i]=0,i++); <br />
　　　　flag=1; <br />
　　　} <br />
　　　else&nbsp;{ <br />
　　　　for(i=1;i&lt;=b[0];b[i]=db[b[0]-i]-&rsquo;0&rsquo;,i++); <br />
　　　　for(i=1;i&lt;=a[0];a[i]=da[a[0]-i]-&rsquo;0&rsquo;,i++); <br />
　　　　for(i=a[0]+1;i&lt;=b[0];a[i]=0,i++); <br />
　　　　for(i=1;i&lt;=b[0]+1;c[i]=0,i++); <br />
　　　} <br />
　　} <br />
　　add(int&nbsp;a[],int&nbsp;b[],int&nbsp;c[])&nbsp;{ <br />
　　　int&nbsp;i,sum; <br />
　　　if(flag==1)&nbsp;{ <br />
　　　　for(i=1;i&lt;=a[0];i++)&nbsp;{ <br />
　　　　　sum=a[i]+b[i]+c[i]; <br />
　　　　　c[i+1]=sum/10; <br />
　　　　　c[i]=sum; <br />
　　　　} <br />
　　　　if(c[a[0]+1]==0) <br />
　　　　　c[0]=a[0]; <br />
　　　　else <br />
　　　　　c[0]=a[0]+1; <br />
　　　} <br />
　　　else&nbsp;{ <br />
　　　　for(i=1;i&lt;=b[0];i++)&nbsp;{ <br />
　　　　　sum=a[i]+b[i]+c[i]; <br />
　　　　　c[i+1]=sum/10; <br />
　　　　　c[i]=sum; <br />
　　　　} <br />
　　　　if(c[b[0]+1]==0) <br />
　　　　　c[0]=b[0]; <br />
　　　　else <br />
　　　　　c[0]=b[0]+1; <br />
　　　} <br />
　　} <br />
　　void&nbsp;print(int&nbsp;m[])&nbsp;{ <br />
　　　int&nbsp;i; <br />
　　　for(i=m[0];i&gt;=1;i--) <br />
　　　　printf(&quot;%d,&quot;,m[i]);&nbsp;PRIN <br />
　　} <br />
　　main(){ <br />
　　　int&nbsp;s; <br />
　　　int&nbsp;a[20],b[20],c[20]; <br />
　　　char&nbsp;da[]={&quot;123456789&quot;}; <br />
　　　char&nbsp;db[]={&quot;12344443&quot;}; <br />
　　　a[0]=strlen(da); <br />
　　　b[0]=strlen(db); <br />
　　　printf(&quot;a[0]=%d &quot;,a[0]); <br />
　　　printf(&quot;b[0]=%d&quot;,b[0]);&nbsp;PRIN <br />
　change(da,db,a,b,c); <br />
　　　printf(&quot;flag=%d &quot;,flag);&nbsp;PRIN <br />
　　　printf(&quot;----------------- &quot;); <br />
　　　if(flag==1)&nbsp;{ <br />
　　　　print(a);&nbsp;PRIN <br />
　　　　s=abs(a[0]-b[0]); <br />
　　　　printf(&quot;+&quot;); <br />
　　　　　for(s=s*2-1;s&gt;0;s--) <br />
　　　　　　printf(&quot;&nbsp;&quot;); <br />
　　　　　　print(b);&nbsp;PRIN <br />
　　　} <br />
　　　else&nbsp;{ <br />
　　　　s=abs(a[0]-b[0]); <br />
　　　　printf(&quot;+&quot;); <br />
　　　　for(s=s*2-1;s&gt;0;s--) <br />
　　　　　printf(&quot;&nbsp;&quot;); <br />
　　　　　print(a);&nbsp;PRIN <br />
　　　　　print(b);&nbsp;PRIN <br />
　　　} <br />
　　　add(a,b,c); <br />
　　　printf(&quot;----------------- &quot;); <br />
　　　print(c); <br />
　　} <br />
<a href="http://www.studa.com/" class="kk" id="studaexam173" target="_blank">时间</a>复杂度计算: <br />
　　●&nbsp;确定基本操作 <br />
　　●&nbsp;计算基本操作次数 <br />
　　●&nbsp;选择T(n) <br />
　　●&nbsp;lim(F(n)/T(n))=c <br />
　　●&nbsp;0(T(n))为<a href="http://www.studa.com/" class="kk" id="studaexam173" target="_blank">时间</a>复杂度 <br />
　　上例子的时间复杂度为O(max_s);&nbsp; <br />
-------------------------------------------------------------------------------- <br />
二:链表 <br />
　　1、知识点 <br />
　　●逻辑次序与物理次序不一致存储<a href="http://www.stsj86.com/" class="kk" id="studaexam154" target="_blank">方法</a>； <br />
　　●单链表的定义：术语（头结点、头指针等） <br />
　　●注意带头结点的单链表与不带头结点的单链表区别。（程序员<a href="http://www.stsj86.com/" class="kk" id="studaexam664" target="_blank">考试</a>一般不考带头结点，因为稍难理解） <br />
　　●插入、删除、遍历（p==NULL表明操作完成）等操作 <br />
　　●&nbsp;循环链表：定义，存储表示，操作； <br />
　　●&nbsp;双向链表：定义，存储<a href="http://www.stsj86.com/" class="kk" id="studaexam154" target="_blank">方法</a>，操作； <br />
　　单链表和循环链表区别在最后一个指针域值不同。 <br />
　<font color="#ffffff" id="rgsdfm18274">转贴于 学生大考试站 http://www.stsj86.com</font><!--分页-->　2、操作 <br />
　　●单链表：插入X，删除X，查找X，计算结点个数 <br />
　　●单链表的逆置（中程曾考） <br />
　　head-&gt;NULL/p-&gt;a1/p-&gt;a2/p-&gt;a3/p&hellip;&hellip;an/NULL&nbsp;注：p代表指针;NULL/p代表头结点 <br />
　　＝》&nbsp;head-&gt;NULL/p-&gt;an/p-&gt;an-1/p-&gt;an-2/p&hellip;&hellip;a1/NULL&nbsp; <br />
　　●循环链表的操作：插入X，删除X，查找X，计算结点个数； <br />
　　　　用p=head-&gt;next来判断一次计算结点个数完成； <br />
　　程序段如下： <br />
　　k=0; <br />
　　do{ <br />
　　　k++; <br />
　　　p=p-&gt;next; <br />
　　}while(p!=head-&gt;next); <br />
　　●&nbsp;双向链表 <br />
　　●多项式相加 <br />
　　●&nbsp;有序链表合并&nbsp; <br />
-------------------------------------------------------------------------------- <br />
　　例程：已知两个字符串S，T，求S和T的最长公子串； <br />
　　1、逻辑结构：字符串 <br />
　　2、存储结构：数组 <br />
　　3、算法：　精化（精细化工）**老顽童注：此处&ldquo;精细化工&rdquo;说明好像不对！ <br />
　　s=&quot;abaabcacb&quot;&nbsp; <br />
　　t=&quot;abdcabcaabcda&quot; <br />
　　当循环到s.len-1时，有两种情况：s=&quot;abaabcacb&quot;、s=&quot;abaabcacb&quot;&nbsp; <br />
　　　　　　s.len-2时，有三种情况：s=&quot;abaabcacb&quot;、s=&quot;abaabcacb&quot;、s=&quot;abaabcacb&quot;&nbsp; <br />
　　　　　　　. <br />
　　　　　　　. <br />
　　　　　　　. <br />
　　　　　　1&nbsp;s.len种情况 <br />
　　程序思路： <br />
tag=0&nbsp;//没有找到 <br />
　　for(l=s.len;l&gt;0&amp;&amp;!tag;l--)&nbsp;{ <br />
　　　判断长度为l的s中的子串是否为t的子串; <br />
　　　若是：tag=1; <br />
　　} <br />
　　长度为l的s的子串在s中有（s.len-l+1）个。 <br />
　　子串0:　0～l-1 <br />
　　　　1:　　　　1～l　　　　　　 <br />
　　　　2:　　　　2～l+1　　　　　　 <br />
　　　　3:　　　　3～l+2 <br />
　　　　　&hellip;&hellip;&nbsp; <br />
　　　　　&hellip;&hellip; <br />
　　　　s.len-l:　s.len-l～s.len-1 <br />
　　由上面可得：第j个子串为j～l+j-1。 <br />
　　判断长度为l的s中的子串是否为t的子串: <br />
　　for(j=0;j　　　判断s中长度为l的第j个子串是否为t的子串; <br />
　　　如果是：tag=1; <br />
　　} <br />
　　模式结构： <br />
　　tag=0; <br />
　　for(l=s.len;l&gt;0&amp;&amp;tag==0;l--)&nbsp;{ <br />
　　　for(j=0;j　　　　??&nbsp;用模式匹配<a href="http://www.stsj86.com/" class="kk" id="studaexam285" target="_blank">方法</a>确定s[j]～s[l+j-1]这个字符串是否为t的子串；&nbsp;//好好想想 <br />
　　&nbsp;　&nbsp;若是，tag=1; <br />
　　　} <br />
　　} <br />
　　在前面笔者编了一些程序:链表,长整型数相加,三元组表转置以及一些简单的函数.其实有些算法想想是很简单,不过写起来还是需要一定耐心和C基础的,如果你自己觉得各算法都很懂了,不妨开机编编试试.或许会有一些新的发现与体会. <br />
栈和队列 <br />
　　1、知识点: <br />
　　●&nbsp;栈的定义:操作受限的线性表 <br />
　　●&nbsp;特点:后进先出 <br />
　　●&nbsp;栈的存储结构:顺序,链接 <br />
　　　/&nbsp;push(s,d) <br />
　　●&nbsp;栈的基本操作: <br />
　　　&nbsp;pop(s) <br />
　　栈定义： <br />
　　struct&nbsp;{ <br />
　　　datatype&nbsp;data[max_num]; <br />
　　　int&nbsp;top; <br />
　　}; <br />
　　●队列定义 <br />
　　特点:先进先出 <br />
　　/入队列&nbsp;in_queue(Q,x) <br />
　　●队列的操作: <br />
　　出队列&nbsp;del_queue(Q) <br />
　　●队列存储结构: <br />
　　链队列: <br />
　　Typedef&nbsp;struct&nbsp;node{ <br />
　　　Datatype&nbsp;data; <br />
　　　Struct&nbsp;node&nbsp;*next; <br />
　　}NODE; <br />
　　Typedef&nbsp;struct&nbsp;{ <br />
　　　NODE&nbsp;*front; <br />
　　　NODE&nbsp;*rear; <br />
　　}Queue; <br />
　　顺序队列: <br />
　　struct&nbsp;{ <br />
　　　datatype&nbsp;data[max_num]; <br />
　　　int&nbsp;front,rear; <br />
　　}; <br />
　　问题: <br />
　　队列&oacute;线性表 <br />
　　假溢出&lt;=循環队列 <br />
　　队列满，队列空条件一样&lt;=浪费一个存储空间 <br />
　　递归 <br />
　　定义：问题规模为N的解依赖于小规模问题的解。问题的求解通过小规模问题的解得到。 <br />
　　包括二个步骤：
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/91707#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 23:21:23 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/91707</link>
        <guid>http://junjie314.javaeye.com/blog/91707</guid>
      </item>
      <item>
        <title>软考常用算法设计方法(二)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/91706" style="color:red;">http://junjie314.javaeye.com/blog/91706</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          分治法的合并步骤是算法的<a href="http://www.stsj86.com/" class="kk" id="studaexam601" target="_blank">关键</a>所在。有些问题的合并<a href="http://www.stsj86.com/" class="kk" id="studaexam749" target="_blank">方法</a>比较明显，有些问题合并<a href="http://www.stsj86.com/" class="kk" id="studaexam749" target="_blank">方法</a>比较复杂，或者是有多种合并方案；或者是合并方案不明显。究竟应该怎样合并，没有统一的模式，需要具体问题具体分析。 <br />
　　【问题】&nbsp;大整数乘法 <br />
　　问题描述： <br />
　　通常，在分析一个算法的计算复杂性时，都将加法和乘法运算当作是基本运算来处理，即将执行一次加法或乘法运算所需的计算<a href="http://www.studa.com/" class="kk" id="studaexam463" target="_blank">时间</a>当作一个仅取决于计算机硬件处理速度的常数。 <br />
　　这个假定仅在计算机硬件能对参加运算的整数直接表示和处理时才是合理的。然而，在某些情况下，我们要处理很大的整数，它无法在计算机硬件能直接表示的范围内进行处理。若用浮点数来表示它，则只能近似地表示它的大小，计算结果中的有效数字也受到限制。若要精确地表示大整数并在计算结果中要求精确地得到所有位数上的数字，就必须用软件的方法来实现大整数的算术运算。 <br />
　　请设计一个有效的算法，可以进行两个n位大整数的乘法运算。 <br />
　　设X和Y都是n位的二进制整数，现在要计算它们的乘积XY。我们可以用小学所学的方法来设计一个计算乘积XY的算法，但是这样做计算步骤太多，显得效率较低。如果将每2个1位数的乘法或加法看作一步运算，那么这种方法要作O(n2)步运算才能求出乘积XY。下面我们用分治法来设计一个更有效的大整数乘积算法。 <br />
　　&nbsp; <br />
　　图6-3&nbsp;大整数X和Y的分段 <br />
　　我们将n位的二进制整数X和Y各分为2段，每段的长为n/2位（为简单起见，假设n是2的幂），如图6-3所示。 <br />
　　由此，X=A2n/2+B，Y=C2n/2+D。这样，X和Y的乘积为： <br />
　　XY=(A2n/2+B)(C2n/2+D)=AC2n+(AD+CB)2n/2+BD&nbsp;（1） <br />
　　如果按式（1）计算XY，则我们必须进行4次n/2位整数的乘法(AC，AD，BC和BD)，以及3次不超过n位的整数加法（分别对应于式（1）中的加号），此外还要做2次移位（分别对应于式（1）中乘2n和乘2n/2）。所有这些加法和移位共用O（n）步运算。设T（n）是2个n位整数相乘所需的运算总数，则由式（1），我们有： <br />
　　&nbsp;（2） <br />
　　由此可得T（n）=O（n2）。因此，用（1）式来计算X和Y的乘积并不比小学生的方法更有效。要想改进算法的计算复杂性，必须减少乘法次数。为此我们把XY写成另一种形式： <br />
　　XY=AC2n+[(A-B)(D-C)+AC+BD]2n/2+BD&nbsp;（3） <br />
　　虽然，式（3）看起来比式（1）复杂些，但它仅需做3次n/2位整数的乘法（AC，BD和（A-B）（D-C）），6次加、减法和2次移位。由此可得： <br />
　　&nbsp;（4） <br />
　　用解递归方程的套用公式法马上可得其解为T(n)=O(nlog3)=O(n1.59)。利用式（3），并考虑到X和Y的符号对结果的影响，我们给出大整数相乘的完整算法MULT如下： <br />
　　function&nbsp;MULT(X，Y，n);&nbsp;{X和Y为2个小于2n的整数，返回结果为X和Y的乘积XY} <br />
　　begin <br />
　　S=SIGN(X)*SIGN(Y);&nbsp;{S为X和Y的符号乘积} <br />
　　X=ABS(X); <br />
　　Y=ABS(Y);&nbsp;{X和Y分别取绝对值} <br />
　　if&nbsp;n=1&nbsp;then <br />
　　if&nbsp;(X=1)<a href="http://www.studa.com/" class="kk" id="studaexam476" target="_blank">and</a>(Y=1)&nbsp;then&nbsp;return(S) <br />
　　else&nbsp;return(0) <br />
　　else&nbsp;begin <br />
　　A=X的左边n/2位; <br />
　　B=X的右边n/2位; <br />
　　C=Y的左边n/2位; <br />
　　D=Y的右边n/2位; <br />
　　ml=MULT(A,C,n/2); <br />
　　m2=MULT(A-B,D-C,n/2); <br />
　　m3=MULT(B,D,n/2);&nbsp; <br />
　　S=S*(m1*2n+(m1+m2+m3)*2n/2+m3); <br />
　　return(S);&nbsp; <br />
　　end; <br />
　　end; <br />
　　上述二进制大整数乘法同样可应用于十进制大整数的乘法以提高乘法的效率减少乘法次数。 <br />
　　
          <br/>
          <span style="color:red;">
            <a href="http://junjie314.javaeye.com/blog/91706#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Jun 2007 23:20:10 +0800</pubDate>
        <link>http://junjie314.javaeye.com/blog/91706</link>
        <guid>http://junjie314.javaeye.com/blog/91706</guid>
      </item>
      <item>
        <title>软考常用算法设计方法(一)</title>
        <author>junjie314</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://junjie314.javaeye.com">junjie314</a>&nbsp;
          链接：<a href="http://junjie314.javaeye.com/blog/91705" style="color:red;">http://junjie314.javaeye.com/blog/91705</a>&nbsp;
          发表时间: 2007年06月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要使计算机能完成人们预定的<a href="http://www.studa.com/" class="kk" id="studaexam625" target="_blank">工作</a>，首先必须为如何完成预定的<a href="http://www.studa.com/" class="kk" id="studaexam625" target="_blank">工作</a>设计一个算法，然后再根据算法编写程序。计算机程序要对问题的每个对象和处理规则给出正确详尽的描述，其中程序的数据结构和变量用来描述问题的对象，程序结构、函数和语句用来描述问题的算法。算法数据结构是程序的两个重要方面。 <br />
　　算法是问题求解过程的精确描述，一个算法由有限条可完全机械地执行的、有确定结果的指令组成。指令正确地描述了要完成的任务和它们被执行的顺序。计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止，或终止于给出问题的解，或终止于指出问题对此输入数据无解。 <br />
　　通常求解一个问题可能会有多种算法可供选择，选择的主要标准是算法的正确性和可靠性，简单性和易理解性。其次是算法所需要的存储空间少和执行更快等。 <br />
　　算法设计是一件非常困难的工作，经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。另外，为了更简洁的形式设计和藐视算法，在算法设计时又常常采用递归技术，用递归描述算法。 <br />
　　一、迭代法 <br />
　　迭代法是用于求方程或方程组近似根的一种常用的算法设计<a href="http://www.stsj86.com/" class="kk" id="studaexam842" target="_blank">方法</a>。设方程为f(x)=0，用某种数学方法导出等价的形式x=g(x)，然后按以下步骤执行： <br />
　　（1）&nbsp;选一个方程的近似根，赋给变量x0； <br />
　　（2）&nbsp;将x0的值保存于变量x1，然后计算g(x1)，并将结果存于变量x0； <br />
　　（3）&nbsp;当x0与x1的差的绝对值还小于指定的精度要求时，重复步骤（2）的计算。 <br />
　　若方程有根，并且用上述方法计算出来的近似根序列收敛，则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为： <br />
　　【算法】迭代法求方程的根 <br />
　　{&nbsp;x0=初始近似根； <br />
　　&nbsp;do&nbsp;{ <br />
　　&nbsp;x1=x0； <br />
　　&nbsp;x0=g(x1)；&nbsp;/*按特定的方程计算新的近似根*/ <br />
　　&nbsp;}&nbsp;while&nbsp;(&nbsp;fabs(x0-x1)&gt;Epsilon)； <br />
　　&nbsp;printf(&ldquo;方程的近似根是%f &rdquo;，x0)； <br />
　　} <br />
　　迭代算法也常用于求方程组的根，令 <br />
　　&nbsp;X=（x0，x1，&hellip;，xn-1） <br />
　　设方程组为： <br />
　　&nbsp;xi=gi(X)&nbsp;(I=0，1，&hellip;，n-1) <br />
　　则求方程组根的迭代算法可描述如下： <br />
　　【算法】迭代法求方程组的根 <br />
　　&nbsp;{&nbsp;for&nbsp;(i=0;i　　&nbsp;x[i]=初始近似根; <br />
　　&nbsp;do&nbsp;{ <br />
　　&nbsp;for&nbsp;(i=0;i　　&nbsp;y[i]=x[i]; <br />
　　&nbsp;for&nbsp;(i=0;i　　&nbsp;x[i]=gi(X); <br />
　　&nbsp;for&nbsp;(delta=0.0,i=0;i　　&nbsp;if&nbsp;(fabs(y[i]-x[i])&gt;delta)&nbsp;delta=fabs(y[i]-x[i])； <br />
　　&nbsp;}&nbsp;while&nbsp;(delta&gt;Epsilon)； <br />
　　&nbsp;for&nbsp;(i=0;i　　&nbsp;printf(&ldquo;变量x[%d]的近似根是&nbsp;%f&rdquo;，I，x[i])； <br />
　　&nbsp;printf(&ldquo; &rdquo;)； <br />
　　&nbsp;} <br />
　　&nbsp;具体使用迭代法求根时应注意以下两种可能发生的情况： <br />
　　（1）&nbsp;如果方程无解，算法求出的近似根序列就不会收敛，迭代过程会变成死循环，因此在使用迭代算法前应先考察方程是否有解，并在程序中对迭代的次数给予限制； <br />
　　（2）&nbsp;方程虽然有解，但迭代公式选择不当，或迭代的初始近似根选择不合理，也会导致迭代失败。 <br />
　　二、穷举搜索法 <br />
　　&nbsp;穷举搜索法是对可能是解的众多候选解按某种顺序进行逐一枚举和检验，并从众找出那些符合要求的候选解作为问题的解。 <br />
　　【问题】&nbsp;将A、B、C、D、E、F这六个变量排成如图所示的三角形，这六个变量分别取[1，6]上的整数，且均不相同。求使三角形三条边上的变量之和相等的全部解。如图就是一个解。 <br />
　　程序引入变量a、b、c、d、e、f，并让它们分别顺序取1至6的证书，在它们互不相同的条件下，测试由它们排成的如图所示的三角形三条边上的变量之和是否相等，如相等即为一种满足要求的排列，把它们输出。当这些变量取尽所有的组合后，程序就可得到全部可能的解。细节见下面的程序。 <br />
　　【程序1】 <br />
　　#&nbsp;include&nbsp; <br />
　　void&nbsp;main() <br />
　　{&nbsp;int&nbsp;a,b,c,d,e,f; <br />
　　&nbsp;for&nbsp;(a=1;a&lt;=6;a++)&nbsp; <br />
　　&nbsp;for&nbsp;(b=1;b&lt;=6;b++)&nbsp;{ <br />
　　&nbsp;if&nbsp;(b==a)&nbsp;continue; <br />
　　&nbsp;for&nbsp;(c=1;c&lt;=6;c++)&nbsp;{ <br />
　　&nbsp;if&nbsp;(c==a)||(c==b)&nbsp;continue; <br />
　　&nbsp;for&nbsp;(d=1;d&lt;=6;d++)&nbsp;{ <br />
　　&nbsp;if&nbsp;(d==a)||(d==b)||(d==c)&nbsp;continue; <br />
　　for&nbsp;(e=1;e&lt;=6;e++)&nbsp;{ <br />
　　&nbsp;if&nbsp;(e==a)||(e==b)||(e==c)||(e==d)&nbsp;continue; <br />
　　f=21-(a+b+c+d+e); <br />
　　if&nbsp;((a+b+c==c+d+e))&amp;&amp;(a+b+c==e+f+a))&nbsp;{ <br />
　　printf(&ldquo;%6d,a); <br />
　　&nbsp;printf(&ldquo;%4d%4d&rdquo;,b,f); <br />
　　&nbsp;printf(&ldquo;%2d%4d%4d&rdquo;,c,d,e); <br />
　　&nbsp;scanf(&ldquo;%*c&rdquo;); <br />
　　} <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　按穷举法编写的程序通常不能适应变化的情况。如问题改成有9个变量排成三角形，每条边有4个变量的情况，程序的循环重数就要相应改变。 <br />
　　&nbsp;对一组数穷尽所有排列，还有更直接的方法。将一个排列看作一个长整数，则所有排列对应着一组整数。将这组整数按从小到大的顺序排列排成一个整数，从对应最小的整数开始。按数列的递增顺序逐一列举每个排列对应的每个整数，这能更有效地完成排列的穷举。从一个排列找出对应数列的下一个排列可在当前排列的基础上作部分调整来实现。倘若当前排列为1，2，4，6，5，3，并令其对应的长整数为124653。要寻找比长整数124653更大的排列，可从该排列的最后一个数字顺序向前逐位考察，当发现排列中的某个数字比它前一个数字大时，如本例中的6比它的前一位数字4大，这说明还有对应更大整数的排列。但为了顺序从小到大列举出所有的排列，不能立即调整得太大，如本例中将数字6与数字4交换得到的排列126453就不是排列124653的下一个排列。为了得到排列124653的下一个排列，应从已经考察过的那部分数字中选出比数字大，但又是它们中最小的那一个数字，比如数字5，与数字4交换。该数字也是从后向前考察过程中第一个比4大的数字。5与4交换后，得到排列125643。在前面数字1，2，5固定的情况下，还应选择对应最小整数的那个排列，为此还需将后面那部分数字的排列顺序颠倒，如将数字6，4，3的排列顺序颠倒，得到排列1，2，5，3，4，6，这才是排列1，2，4，6，5，3的下一个排列。按以上想法编写的程序如下。 <br />
　　【程序2】 <br />
　　#&nbsp;include&nbsp; <br />
　　#&nbsp;define&nbsp;SIDE_N&nbsp;3 <br />
　　#&nbsp;define&nbsp;LENGTH&nbsp;3 <br />
　　#&nbsp;define&nbsp;VARIABLES&nbsp;6 <br />
　　int&nbsp;A,B,C,D,E,F; <br />
　　int&nbsp;*pt[]={&amp;A,&amp;B,&amp;C,&amp;D,&amp;E,&amp;F}; <br />
　　int&nbsp;*side[SIDE_N][LENGTH]={&amp;A,&amp;B,&amp;C,&amp;C,&amp;D,&amp;E,&amp;E,&amp;F,&amp;A}; <br />
　　int&nbsp;side_total[SIDE_N]; <br />
　　main{} <br />
　　{&nbsp;int&nbsp;i,j,t,equal; <br />
　　&nbsp;for&nbsp;(j=0;j　　&nbsp;*pt[j]=j+1; <br />
　　&nbsp;while(1) <br />
　　&nbsp;{&nbsp;for&nbsp;(i=0;i　　&nbsp;{&nbsp;for&nbsp;(t=j=0;j　　&nbsp;t+=*side[i][j]; <br />
　　&nbsp;side_total[i]=t; <br />
　　&nbsp;} <br />
　　&nbsp;for&nbsp;(equal=1,i=0;equal&amp;&amp;i　　&nbsp;if&nbsp;(side_total[i]!=side_total[i+1]&nbsp;equal=0; <br />
　　&nbsp;if&nbsp;(equal) <br />
　　&nbsp;{&nbsp;for&nbsp;(i=1;i　　&nbsp;printf(&ldquo;%4d&rdquo;,*pt[i]); <br />
　　&nbsp;printf(&ldquo; &rdquo;); <br />
　　&nbsp;scanf(&ldquo;%*c&rdquo;); <br />
　　&nbsp;} <br />
　　&nbsp;for&nbsp;(j=VARIABLES-1;j&gt;0;j--) <br />
　　&nbsp;if&nbsp;(*pt[j]&gt;*pt[j-1])&nbsp;break; <br />
　　&nbsp;if&nbsp;(j==0)&nbsp;break; <br />
　　&nbsp;for&nbsp;(i=VARIABLES-1;i&gt;=j;i--) <br />
　　&nbsp;if&nbsp;(*pt[i]&gt;*pt[i-1])&nbsp;break; <br />
　　&nbsp;t=*pt[j-1];*&nbsp;pt[j-1]&nbsp;=*&nbsp;pt[i];&nbsp;*pt[i]=t; <br />
　　&nbsp;for&nbsp;(i=VARIABLES-1;i&gt;j;i--,j++) <br />
　　&nbsp;{&nbsp;t=*pt[j];&nbsp;*pt[j]&nbsp;=*&nbsp;pt[i];&nbsp;*pt[i]=t;&nbsp;} <br />
　　&nbsp;} <br />
　　} <br />
　　从上述问题解决的方法中，最重要的因素就是确定某种方法来确定所有的候选解。下面再用一个示例来加以说明。 <br />
　　【问题】&nbsp;背包问题 <br />
　　问题描述：有不同价值、不同重量的物品n件，求从这n件物品中选取一部分物品的选择方案，使选中物品的总重量不超过指定的限制重量，但选中物品的价值之和最大。 <br />
　　设n个物品的重量和价值分别存储于数组w[&nbsp;]和v[&nbsp;]中，限制重量为tw。考虑一个n元组（x0，x1，&hellip;，xn-1），其中xi=0&nbsp;表示第i个物品没有选取，而xi=1则表示第i个物品被选取。显然这个n元组等价于一个选择方案。用枚举法解决背包问题，需要枚举所有的选取方案，而根据上述方法，我们只要枚举所有的n元组，就可以得到问题的解。 <br />
　　显然，每个分量取值为0或1的n元组的个数共为2n个。而每个n元组其实对应了一个长度为n的二进制数，且这些二进制数的取值范围为0～2n-1。因此，如果把0～2n-1分别转化为相应的二进制数，则可以得到我们所需要的2n个n元组。 <br />
　　<font color="#ffffff" id="rgsdfm17330">转贴于 学生大考试站 http://www.stsj86.com</font><!--分页-->【算法】 <br />
　　maxv=0; <br />
　　for&nbsp;(i=0;i&lt;2n;i++) <br />
　　{&nbsp;B[0..n-1]=0; <br />
　　&nbsp;把i转化为二进制数，存储于数组B中; <br />
　　&nbsp;temp_w=0; <br />
　　&nbsp;temp_v=0; <br />
　　&nbsp;for&nbsp;(j=0;j　　&nbsp;{&nbsp;if&nbsp;(B[j]==1) <br />
　　&nbsp;{&nbsp;temp_w=temp_w+w[j]; <br />
　　&nbsp;temp_v=temp_v+v[j]; <br />
　　&nbsp;} <br />
　　&nbsp;if&nbsp;((temp_w&lt;=tw)&amp;&amp;(temp_v&gt;maxv)) <br />
　　&nbsp;{&nbsp;maxv=temp_v; <br />
　　&nbsp;保存该B数组； <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　} <br />
　　 <br />
　　三、递推法 <br />
　　&nbsp;递推法是利用问题本身所具有的一种递推关系求问题解的一种<a href="http://www.stsj86.com/" class="kk" id="studaexam331" target="_blank">方法</a>。设要求问题规模为N的解，当N=1时，解或为已知，或能非常方便地得到解。能采用递推法构造算法的问题有重要的递推性质，即当得到问题规模为i-1的解后，由问题的递推性质，能从已求得的规模为1，2，&hellip;，i-1的一系列解，构造出问题规模为I的解。这样，程序可从i=0或i=1出发，重复地，由已知至i-1规模的解，通过递推，获得规模为i的解，直至得到规模为N的解。 <br />
　　【问题】&nbsp;阶乘计算 <br />
　　问题描述：编写程序，对给定的n（n≦100），计算并输出k的阶乘k！（k=1，2，&hellip;，n）的全部有效数字。 <br />
　　由于要求的整数可能大大超出一般整数的位数，程序用一维数组存储长整数，存储长整数数组的每个元素只存储长整数的一位数字。如有m位成整数N用数组a[&nbsp;]存储： <br />
　　&nbsp;N=a[m]&times;10m-1+a[m-1]&times;10m-2+&nbsp;&hellip;&nbsp;+a[2]&times;101+a[1]&times;100 <br />
　　并用a[0]存储长整数N的位数m，即a[0]=m。按上述约定，数组的每个元素存储k的阶乘k！的一位数字，并从低位到高位依次存于数组的第二个元素、第三个元素&hellip;&hellip;。例如，5！=120，在数组中的存储形式为： <br />
　　3&nbsp;0&nbsp;2&nbsp;1&nbsp;&hellip;&hellip; <br />
　　首元素3表示长整数是一个3位数，接着是低位到高位依次是0、2、1，表示成整数120。 <br />
　　&nbsp;计算阶乘k！可采用对已求得的阶乘(k-1)！连续累加k-1次后求得。例如，已知4！=24，计算5！，可对原来的24累加4次24后得到120。细节见以下程序。 <br />
　　#&nbsp;include&nbsp; <br />
　　#&nbsp;include&nbsp; <br />
　　#&nbsp;define&nbsp;MAXN&nbsp;1000 <br />
　　void&nbsp;pnext(int&nbsp;a[&nbsp;],int&nbsp;k) <br />
　　{&nbsp;int&nbsp;*b,m=a[0],i,j,r,carry; <br />
　　&nbsp;b=(int&nbsp;*&nbsp;)&nbsp;malloc(sizeof(int)*&nbsp;(m+1)); <br />
　　&nbsp;for&nbsp;(&nbsp;i=1;i&lt;=m;i++)&nbsp;b[i]=a[i]; <br />
　　&nbsp;for&nbsp;(&nbsp;j=1;j&lt;=k;j++) <br />
　　&nbsp;{&nbsp;for&nbsp;(&nbsp;carry=0,i=1;i&lt;=m;i++) <br />
　　&nbsp;{&nbsp;r=(i　　&nbsp;a[i]=r%10; <br />
　　&nbsp;carry=r/10; <br />
　　&nbsp;} <br />
　　&nbsp;if&nbsp;(carry)&nbsp;a[++m]=carry; <br />
　　&nbsp;} <br />
　　&nbsp;free(b); <br />
　　&nbsp;a[0]=m; <br />
　　} <br />
　　 <br />
　　void&nbsp;write(int&nbsp;*a,int&nbsp;k) <br />
　　{&nbsp;int&nbsp;i; <br />
　　&nbsp;printf(&ldquo;%4d！=&rdquo;,k); <br />
　　&nbsp;for&nbsp;(i=a[0];i&gt;0;i--) <br />
　　&nbsp;printf(&ldquo;%d&rdquo;,a[i]); <br />
　　printf(&ldquo; &rdquo;); <br />
　　} <br />
　　 <br />
　　void&nbsp;main() <br />
　　{&nbsp;int&nbsp;a[MAXN],n,k; <br />
　　&nbsp;printf(&ldquo;Enter&nbsp;the&nbsp;number&nbsp;n:&nbsp;&ldquo;); <br />
　　&nbsp;scanf(&ldquo;%d&rdquo;,&amp;n); <br />
　　&nbsp;a[0]=1; <br />
　　&nbsp;a[1]=1; <br />
　　&nbsp;write(a,1); <br />
　　&nbsp;for&nbsp;(k=2;k&lt;=n;k++) <br />
　　&nbsp;{&nbsp;pnext(a,k); <br />
　　&nbsp;write(a,k); <br />
　　&nbsp;getchar(); <br />
　　&nbsp;} <br />
　　} <br />
　　四、递归 <br />
　　&nbsp;递归是设计和描述算法的一种有力的工具，由于它在复杂算法的描述中被经常采用，为此在进一步介绍其他算法设计<a href="http://www.stsj86.com/" class="kk" id="studaexam331" target="_blank">方法</a>之前先讨论它。 <br />
　　&nbsp;能采用递归描述的算法通常有这样的特征：为求解规模为N的问题，设法将它分解成规模较小的问题，然后从这些小问题的解方便地构造出大问题的解，并且这些规模较小的问题也能采用同样的分解和综合方法，分解成规模更小的问题，并从这些更小问题的解构造出规模较大问题的解。特别地，当规模N=1时，能直接得解。 <br />
　　【问题】&nbsp;编写计算斐波那契（Fibonacci）数列的第n项函数fib（n）。 <br />
　　&nbsp;斐波那契数列为：0、1、1、2、3、&hellip;&hellip;，即： <br />
　　&nbsp;fib(0)=0; <br />
　　&nbsp;fib(1)=1; <br />
　　&nbsp;fib(n)=fib(n-1)+fib(n-2)&nbsp;（当n&gt;1时）。 <br />
　　写成递归函数有： <br />
　　int&nbsp;fib(int&nbsp;n) <br />
　　{&nbsp;if&nbsp;(n==0)&nbsp;return&nbsp;0; <br />
　　&nbsp;if&nbsp;(n==1)&nbsp;return&nbsp;1; <br />
　　&nbsp;if&nbsp;(n&gt;1)&nbsp;return&nbsp;fib(n-1)+fib(n-2); <br />
　　} <br />
　　&nbsp;递归算法的执行过程分递推和回归两个阶段。在递推阶段，把较复杂的问题（规模为n）的求解推到比原问题简单一些的问题（规模小于n）的求解。例如上例中，求解fib(n)，把它推到求解fib(n-1)和fib(n-2)。也就是说，为计算fib(n)，必须先计算fib(n-1)和fib(n-2)，而计算fib(n-1)和fib(n-2)，又必须先计算fib(n-3)和fib(n-4)。依次类推，直至计算fib(1)和fib(0)，分别能立即得到结果1和0。在递推阶段，必须要有终止递归的情况。例如在函数fib中，当n为1和0的情况。 <br />
　　&nbsp;在回归阶段，当获得最简单情况的解后，逐级返回，依次得到稍复杂问题的解，例如得到fib(1)和fib(0)后，返回得到fib(2)的结果，&hellip;&hellip;，在得到了fib(n-1)和fib(n-2)的结果后，返回得到fib(n)的结果。 <br />
　　&nbsp;在编写递归函数时要注意，函数中的局部变量和参数知识局限于当前调用层，当递推进入&ldquo;简单问题&rdquo;层时，原来层次上的参数和局部变量便被隐蔽起来。在一系列&ldquo;简单问题&rdquo;层，它们各有自己的参数和局部变量。 <br />
　　&nbsp;由于递归引起一系列的函数调用，并且可能会有一系列的重复计算，递归算法的执行效率相对较低。当某个递归算法能较方便地转换成递推算法时，通常按递推算法编写程序。例如上例计算斐波那契数列的第n项的函数fib(n)应采用递推算法，即从斐波那契数列的前两项出发，逐次由前两项计算出下一项，直至计算出要求的第n项。 <br />
　　【问题】&nbsp;组合问题 <br />
　　问题描述：找出从自然数1、2、&hellip;&hellip;、n中任取r个数的所有组合。例如n=5，r=3的所有组合为：&nbsp;（1）5、4、3&nbsp;（2）5、4、2&nbsp;（3）5、4、1 <br />
　　&nbsp;（4）5、3、2&nbsp;（5）5、3、1&nbsp;（6）5、2、1 <br />
　　&nbsp;（7）4、3、2&nbsp;（8）4、3、1&nbsp;（9）4、2、1 <br />
　　&nbsp;（10）3、2、1 <br />
　　&nbsp;分析所列的10个组合，可以采用这样的递归思想来考虑求组合函数的算法。设函数为void&nbsp;comb(int&nbsp;m,int&nbsp;k)为找出从自然数1、2、&hellip;&hellip;、m中任取k个数的所有组合。当组合的第一个数字选定时，其后的数字是从余下的m-1个数中取k-1数的组合。这就将求m个数中取k个数的组合问题转化成求m-1个数中取k-1个数的组合问题。设函数引入<a href="http://www.studa.com/" class="kk" id="studaexam461" target="_blank">工作</a>数组a[&nbsp;]存放求出的组合的数字，约定函数将确定的k个数字组合的第一个数字放在a[k]中，当一个组合求出后，才将a[&nbsp;]中的一个组合输出。第一个数可以是m、m-1、&hellip;&hellip;、k，函数将确定组合的第一个数字放入数组后，有两种可能的选择，因还未去顶组合的其余元素，继续递归去确定；或因已确定了组合的全部元素，输出这个组合。细节见以下程序中的函数comb。 <br />
　　【程序】 <br />
　　#&nbsp;include&nbsp; <br />
　　#&nbsp;define&nbsp;MAXN&nbsp;100 <br />
　　int&nbsp;a[MAXN]; <br />
　　void&nbsp;comb(int&nbsp;m,int&nbsp;k) <br />
　　{&nbsp;int&nbsp;i,j; <br />
　　&nbsp;for&nbsp;(i=m;i&gt;=k;i--) <br />
　　&nbsp;{&nbsp;a[k]=i; <br />
　　&nbsp;if&nbsp;(k&gt;1) <br />
　　&nbsp;comb(i-1,k-1); <br />
　　&nbsp;else <br />
　　&nbsp;{&nbsp;for&nbsp;(j=a[0];j&gt;0;j--) <br />
　　&nbsp;printf(&ldquo;%4d&rdquo;,a[j]); <br />
　　&nbsp;printf(&ldquo; &rdquo;); <br />
　　&nbsp;} <br />
　　&nbsp;} <br />
　　} <br />
　　 <br />
　　void&nbsp;main() <br />
　　{&nbsp;a[0]=3; <br />
　　&nbsp;comb(5,3); <br />
　　} <br />
　　【问题】&nbsp;背包问题 <br />
　　问题描述：有不同价值、不同重量的物品n件，求从这n件物品中选取一部分物品的选择方案，使选中物品的总重量不超过指定的限制重量，但选中物品的价值之和最大。 <br />
　　设n件物品的重量分别为w0、w1、&hellip;、wn-1，物品的价值分别为v0、v1、&hellip;、vn-1。采用递归寻找物品的选择方案。设前面已有了多种选择的方案，并保留了其中总价值最大的方案于数组option[&nbsp;]，该方案的总价值存于变量maxv。当前正在考察新方案，其物品选择情况保存于数组cop[&nbsp;]。假定当前方案已考虑了前i-1件物品，现在要考虑第i件物品；当前方案已包含的物品的重量之和为tw；至此，若其余物品都选择是可能的话，本方案能达到的总价值的期望值为tv。算法引入tv是当一旦当前方案的总价值的期望值也小于前面方案的总价值maxv时，继续考察当前方案变成无意义的<a href="http://www.studa.com/" class="kk" id="studaexam461" target="_blank">工作</a>，应终止当前方案，立即去考察下一个方案。因为当方案的总价值不比maxv大时，该方案不会被再考察，这同时保证函数后找到的方案一定会比前面的方案更好。 <br />
　　对于第i件物品的选择考虑有两种可能： <br />
　　（1）&nbsp;考虑物品i被选择，这种可能性仅当包含它不会超过方案总重量限制时才是可行的。选中后，继续递归去考虑其余物品的选择。 <br />
　　（2）&nbsp;考虑物品i不被选择，这种可能性仅当不包含物品i也有可能会找到价值更大的方案的情况。 <br />
　　按以上思想写出递归算法如下： <br />
　　try(物品i，当前选择已达到的重量和，本方案可能达到的总价值tv) <br />
　　{&nbsp;/*考虑物品i包含在当前方案中的可能性*/ <br />
　　&nbsp;if(包含物品i是可以接受的) <br />
　　&nbsp;{&nbsp;将物品i包含在当前方案中； <br />
　　&nbsp;if&nbsp;(i　　&nbsp;try(i+1,tw+物品i的重量,tv); <br />
　　&nbsp;else <br />
　　&nbsp;/*又一个完整方案，因为它比前面的方案好，以它作为最佳方案*/ <br />
　　以当前方案作为临时最佳方案保存; <br />
　　&nbsp;恢复物品i不包含状态； <br />
　　&nbsp;} <br />
　　&nbsp;/*考虑物品i不包含在当前方案中的可能性*/ <br />
　　&nbsp;if&nbsp;(不包含物品i仅是可男考虑的) <br />
　　&nbsp;if&nbsp;(i　　&nbsp;try(i+1,tw,tv-物品i的价值)； <br />
　　&nbsp;else <br />
　　&nbsp;/*又一个完整方案，因它比前面的方案好，以它作为最佳方案*/ <br />
　　以当前方案作为临时最佳方案保存; <br />
　　&nbsp;} <br />
　　&nbsp;为了理解上述算法，特举以下实例。设有4件物品，它们的重量和价值见表： <br />
　　物品&nbsp;0&nbsp;1&nbsp;2&nbsp;3 <br />
　　重量&nbsp;5&nbsp;3&nbsp;2&nbsp;1 <br />
　　价值&nbsp;4&nbsp;4&nbsp;3&nbsp;1 <br />
　　 <br />
　　并设限制重量为7。则按以上算法，下图表示找解过程。由图知，一旦找到一个解，算法就进一步找更好的佳。如能判定某个查找分支不会找到更好的解，算法不会在该分支继续查找，而是立即终止该分支，并去考察下一个分支。 <br />
　　 <br />
　　按上述算法编写函数和程序如下： <br />
　　【程序】 <br />
　　#&nbsp;include&nbsp; <br />
　　#&nbsp;define&nbsp;N&nbsp;100 <br />
　　double&nbsp;limitW,totV,maxV; <br />
　　int&nbsp;option[N],cop[N]; <br />
　　struct&nbsp;{&nbsp;double&nbsp;weight; <br />
　　&nbsp;double&nbsp;value; <br />
　　&nbsp;}a[N]; <br />
　　int&nbsp;n; <br />
　　void&nbsp;find(int&nbsp;i,double&nbsp;tw,double&nbsp;tv) <br />
　　{&nbsp;int&nbsp;k; <br />
　　&nbsp;/*考