﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶，孰蝶是我，我是孰蝶？一梦至今，蝶我已难分-随笔分类-数据结构与算法</title><link>http://www.blogjava.net/killme2008/category/20137.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 05 May 2008 12:27:51 GMT</lastBuildDate><pubDate>Mon, 05 May 2008 12:27:51 GMT</pubDate><ttl>60</ttl><item><title>使用Rope来高效处理长字符串</title><link>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 05 May 2008 10:41:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/198532.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/198532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/198532.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 前段时间看了这篇文章《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》。这两天为了提高工作中某个系统对外接口的效率，才认真学习了一番。本质上Ropes是将字符串表示为一棵二叉树，特别适用于长字符串的处理，貌似c++ STL库中也有这么个实现。具体实现和原理还是看这篇<a href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">paper</a>。《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》一文中给出的测试数据相当惊人，Ropes比之String和StringBuffer在append,insert,delete等操作上的效率都有一个数量级以上的差距。跑下作者给出的测试程序，其实在测试的字符串不是很长的情况下，这个差距并没有那么大，这也从侧面说明了Rope的应用范围：即只有在大量修改大型字符串的应用程序中才能看到明显的性能提升。那么是否可以用Rope替代StringBuffer做append生成字符串（比如我要的生成xml)。作者也说啦：<br />
&nbsp; &#8220;由于 <code>Rope</code> 的附加性能通常比 <code>StringBuffer</code> 好，这时使用 rope
是否有意义呢？答案还是否。不论何时将输入的数据组合在一起形成格式化输出时，最漂亮最有效的方法是使用模板引擎（例如 StringTemplate
或 FreeMarker）。这种方法不仅能干净地将表示标记与代码分开，而且模板只进行一次编译（通常编译为 JVM
字节码），以后可以重用，从而使它们拥有极佳的性能特征。&#8221;<br />
<br />
&nbsp;&nbsp;&nbsp; 我用Rope for java替代了StringBuffer做XML生成，效率提升在5%-30%左右，xml字符串不是很长，这个提升显然有限，也带来了不必要的复杂度。因此最后还是用Velocity模板引擎来生成XML，测试的结果效率并没有多少改善，但是显然更容易维护和开发了。回到Rope的话题，我用Ruby实现了个版本，Rubyforge上有一个Rope的实现，但是看了源码，与paper所述算法有点差异，因此照着Rope for java也实现了一个<a href="http://code.google.com/p/rope4r/">Rope4r</a>。测试的结果证明在长字符串的累积操作上，Rope4r的append比之String的+=性能可以快上3倍左右，而如果采用String的&lt;&lt;操作，不是immutable的，当然是最快了；比较郁闷的是slice和insert操作都比String的慢上几倍，因为Ruby的String、Array的内建对象都是直接用c写成并做了优化的，我猜测原因在这。<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/198532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-05-05 18:41 <a href="http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>善用表驱动法</title><link>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 17 Apr 2008 11:50:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/193852.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/193852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/193852.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 最近碰到个需求，计算游戏得分的规则，类似这样：<br />
<table class="MsoNormalTable" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">游戏人数</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第一名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第二名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第三名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第四名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">二人</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">100%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">二人</span></strong><span style="font-size: 9pt; font-family: 宋体; color: red;">（出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">2</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时）</span><strong><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">70%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">30%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.25pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span></strong><span style="font-family: 宋体; color: red;">（</span><span style="font-size: 9pt; font-family: 宋体; color: red;">出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">3</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时</span><span style="font-family: 宋体; color: red;">）</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.25pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span></strong><span style="font-size: 9pt; color: red;" lang="EN-US">(</span><span style="font-size: 9pt; font-family: 宋体; color: red;">出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">2</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时</span><span style="font-size: 9pt; color: red;" lang="EN-US">)</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%</span><span style="font-family: 宋体; color: red;">&#215;</span><span style="color: red;" lang="EN-US">2<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
    </tbody>
</table>
......<br />
......<br />
&nbsp;&nbsp;&nbsp; 这些奖励规则没有什么规律，随着人数增多，就越发复杂了，并且业务人员可能随时改变这些规则。<br />
&nbsp;&nbsp;&nbsp; 显然，奖励规则可以采用策略模式，定义策略接口，根据游戏人数定义不同的规则，本质上就是利用动态的多态调用。可以想见，还是少不了复杂的case...when语句，以及繁多的代码。恰好最近读《unix编程艺术》和《代码大全2》，两者都提到一个结论：人类阅读复杂数据结构远比复杂的控制流程容易，或者说数据驱动开发是非常有价值的。《代码大全2》声称这个是表驱动法。因此，这个奖励系数的计算，能否转化成一个查表过程呢？注意到，在游戏中，名次是根据个人的积分在所有玩家中的排位来决定，大概会有这么个排序的玩家积分数组[100,50,3]，这个数组表示3个玩家，第一名100分，第二名50分，第三名才3分。依据规则，第一名的奖励系数就是0.7，第二名就是0.3。我想到类似这样的数组其实都有个形式表示它们的内置结构，比如[100,50,3]数组的&#8220;结构&#8221;是"111"，代表3个位置都有一个人。将"111"作为关键码去查表不就OK了？<br />
&nbsp;&nbsp;&nbsp; 将每个排好序的积分数组解码为这样的关键码，然后去查预先写好的奖励系数表，这个奖励系数表大概类似：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;@@award_rate_hash</span><span style="color: #000000;">=</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">11</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">20</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">111</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">300</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.33</span><span style="color: #000000;">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">201</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">120</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1111</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.65</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.30</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.05</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">4000</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.25</span><span style="color: #000000;">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">3001</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.33</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1300</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2020</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1201</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.15</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1120</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2011</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.35</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; 一个三级hash表，首先根据玩家人数查到特定的系数表，比如要查3个玩家、积分数组是[100,50,3]的奖励系数表就是<span style="color: #000000;">&nbsp; @@award_rate_hash</span><span style="color: #000000;">[:"3"]，然后积分数组</span>[100,50,3]<span style="color: #000000;">解码为:"111"，继续查，如此规则的奖励系数表就是</span><span style="color: #000000;">@@award_rate_hash</span><span style="color: #000000;">[:"3"][</span><span style="color: #000000;">:"111"]——也就是</span><span style="color: #000000;"> </span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}，那么查积分是100的玩家系数就是</span><span style="color: #000000;">@@award_rate_hash</span><span style="color: #000000;">[:"3"][</span><span style="color: #000000;">:"111"][</span>([100,50,3].index(100)+1<span style="color: #000000;">).to_s.to_sym]，也就是</span><span style="color: #000000;">:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">。</span>[100,50,3].index(100)+1<span style="color: #000000;">就是积分100的玩家在数组中的名次(即1)，也就是:"1"指向的结果0.7</span>。其他玩家的查表过程与此类似，不细说了。<br />
&nbsp;&nbsp;&nbsp; 这样，我们所有的奖励规则就是维护这么一张hash表，这个表看起来复杂，其实完全可以自动生成，让业务人员来提供样例数据，解码样例数据并生成这个表是很简单的事情。积分数组的&#8220;解码&#8221;，我给一个Ruby版本：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">#</span><span style="color: #008000;">解码数组为字符串关键码</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> decode_array(array)<br />
&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000;">=</span><span style="color: #000000;">array.size<br />
&nbsp;&nbsp;&nbsp;&nbsp;trace_list</span><span style="color: #000000;">=</span><span style="color: #000000;">[]<br />
&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">=</span><span style="color: #000000;">[]<br />
&nbsp;&nbsp;&nbsp;&nbsp;len.times&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">time</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result[time]</span><span style="color: #000000;">=</span><span style="color: #000000;">0&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace_list[time]</span><span style="color: #000000;">=</span><span style="color: #000000;">false<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;array.each_with_index&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">item,index</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result[index]</span><span style="color: #000000;">=</span><span style="color: #000000;">count_times(array,trace_list,index,len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result.join(</span><span style="color: #800000;">''</span><span style="color: #000000;">).to_sym<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> count_times(array,trace_list,index,len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;item</span><span style="color: #000000;">=</span><span style="color: #000000;">array[index]<br />
&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">=</span><span style="color: #000000;">0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(index..len).each&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">i</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;array[i]</span><span style="color: #000000;">==</span><span style="color: #000000;">item&nbsp;</span><span style="color: #0000ff;">and</span><span style="color: #000000;">&nbsp;!trace_list[i]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">+=</span><span style="color: #000000;">1</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace_list[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result<br />
&nbsp;&nbsp;end</span></div>
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/193852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-04-17 19:50 <a href="http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于binary search</title><link>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 02 Apr 2008 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/190285.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/190285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/190285.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 编程珠玑Column 4关于binary search的部分相当精彩，<font face="Courier New">1946年就有人发表binary search，但直到1962第一个正确运行的算法才写出来。尽管算法描述看起来简单明了，但是要写的正确却是有许多地方要仔细考虑。作者着重强调的是对程序正确性的分析方法，仔细分析方法的</font><font face="Courier New">pre-condition, invariant,和post-condition。</font>g9老大翻译过Joshua Bloch在google blog上的文章《<a href="http://blog.csdn.net/g9yuayon/archive/2006/06/04/772382.aspx">号外，号外，几乎所有的binary search和mergsort都有错</a>》，原文在<a href="http://feeds.feedburner.com/~r/blogspot/gJZg/~3/144582870/extra-extra-read-all-about-it-nearly.html">这里</a>。今天看了下原文，有更新，对于求中值索引的c/c++方法原文仍然是有错的，本来是这样：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;((unsigned)&nbsp;(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;high))&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">。</span></div>
<br />
但是在c99标准中，对于两个signed数值之和，如果溢出结果是未定义的(undefined)，也就是说与编译器实现相关。上面的代码应该修改为：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;((unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)high))&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;</span></div>
<br />
我查了下jdk6的java.util.Arrays的源码，joshua bloch说的这个问题已经解决，现在的binary search如下：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Like&nbsp;public&nbsp;version,&nbsp;but&nbsp;without&nbsp;range&nbsp;checks.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;binarySearch0(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;fromIndex,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;toIndex,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;low&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fromIndex;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;high&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;toIndex&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(low&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;high)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;high)&nbsp;</span><span style="color: #000000;">&gt;&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;midVal&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[mid];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(midVal&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(midVal&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;high&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mid;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;key&nbsp;found</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;key&nbsp;not&nbsp;found.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
&nbsp;&nbsp;&nbsp; 如原文所讨论的，采用了&gt;&gt;&gt;操作符替代除以2<img src ="http://www.blogjava.net/killme2008/aggbug/190285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-04-02 10:08 <a href="http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>位图排序</title><link>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 07 Jan 2008 07:30:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/173362.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/173362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/173362.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 《编程珠玑》第一章第一题就相当的精彩，做个笔记。题目如下：<br />
输入:&nbsp;&nbsp; 一个包含n个正整数的文件，每个正整数小于n,n等于10的7次方（一千万）。并且文件内的正整数没有重复和关联数据。<br />
<br />
输出:&nbsp; 输入整数的升序排列<br />
&nbsp;<br />
约束： 限制在1M左右内存，充足的磁盘空间<br />
<br />
&nbsp;&nbsp;&nbsp; 假设整数占32位，1M内存可以存储大概250000个整数，第一个方法就是采用基于磁盘的合并排序算法，第二个办法就是将0-9999999切割成40个区间，分40次扫描（10000000/250000)，每次读入250000个在一个区间的整数，并在内存中使用快速排序。书中提出的第三个解决办法是采用bitmap（或者称为bit vector）来表示所有数据集合（注意到条件，数据没有重复），这样就可以一次性将数据读入内存，减少了扫描次数。算法的伪代码如下：<br />
阶段1：初始化一个空集合<br />
&nbsp;&nbsp;&nbsp;&nbsp; for i=[0,n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit[i]=0;<br />
阶段2：读入数据i，并设置bit[i]=1<br />
&nbsp;&nbsp;&nbsp; for each i in the input file<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit[i]=1;<br />
阶段3：输出排序的结果<br />
&nbsp;&nbsp; for i=[0,n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if bit[i]==1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; write i on the output file<br />
<br />
这个算法的时间复杂度在O(n)，用c语言写的版本可以在10秒内完成任务！c语言的源码在该书主页上有，这里给一个java的测试版，加上我的理解注释：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;"><br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;Created&nbsp;by&nbsp;IntelliJ&nbsp;IDEA.<br />
&nbsp;*&nbsp;User: zhuangxd<br />
&nbsp;*&nbsp;Date:&nbsp;2008-1-7<br />
&nbsp;*&nbsp;Time:&nbsp;14:30:44<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BitSortTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;BITSPERWORD&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">32</span><span style="color: #000000;">;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">整数位数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;SHIFT&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">5</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;MASK&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0x1F</span><span style="color: #000000;">;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">5位遮蔽 0B11111</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;N&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10000000</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">用int数组来模拟位数组，总计(1&nbsp;+&nbsp;N&nbsp;/&nbsp;BITSPERWORD)*BITSPERWORD位，足以容纳N</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;N&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;BITSPERWORD)];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bitsort(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]{</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">100</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">10000</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">9999</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">4567</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">78902</span><span style="color: #000000;">});<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;bitsort(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;array)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;N;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clr(i);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">位数组所有位清0</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;array.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set(array[i]);&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">阶段2</span><br />
<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;N;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(test(i))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">置a[i&gt;&gt;SHIFT]的第(i&nbsp;&amp;&nbsp;MASK)位为1，</span><span style="color: #008000;">也就是位数组的第i位为1</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;set(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">|=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">置a[i&gt;&gt;SHIFT]的第(i&nbsp;&amp;&nbsp;MASK)位为0,也就是位数组的第i位为0</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clr(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">&amp;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">测试位数组的第i位是否为1</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;test(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK)))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/173362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-07 15:30 <a href="http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单LRU算法实现缓存-update2</title><link>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 29 Sep 2007 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/149645.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/149645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/149645.html</trackback:ping><description><![CDATA[update1:第二个实现，读操作不必要采用独占锁，缓存显然是读多于写，读的时候一开始用独占锁是考虑到要递增计数和更新时间戳要加锁，不过这两个变量都是采用原子变量，因此也不必采用独占锁，修改为读写锁。<br />
update2:一个错误，老是写错关键字啊，<span style="color: #000000;">LRUCache的</span><span style="color: #000000;">maxCapacity应该声明为volatile，而不是transient。</span><br />
&nbsp;&nbsp;  <br />
&nbsp;&nbsp; 最简单的LRU算法实现，就是利用jdk的LinkedHashMap，覆写其中的removeEldestEntry(Map.Entry)方法即可，如下所示：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.ArrayList;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Collection;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.LinkedHashMap;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.Lock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Map;<br />
<br />
<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;类说明：利用LinkedHashMap实现简单的缓存，&nbsp;必须实现removeEldestEntry方法，具体参见JDK文档<br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@author</span><span style="color: #008000;">&nbsp;dennis<br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;K&gt;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;V&gt;<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;LRULinkedHashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;LinkedHashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">float</span><span style="color: #000000;">&nbsp;DEFAULT_LOAD_FACTOR&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0.75f</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;lock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReentrantLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRULinkedHashMap(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">(maxCapacity,&nbsp;DEFAULT_LOAD_FACTOR,&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.maxCapacity&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;removeEldestEntry(java.util.Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;eldest)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;size()&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;containsKey(Object&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.containsKey(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;get(Object&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;put(K&nbsp;key,&nbsp;V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.put(key,&nbsp;value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;size()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clear()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.clear();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Collection</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;getAll()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ArrayList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">(</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.entrySet());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
&nbsp;&nbsp;&nbsp; 如果你去看LinkedHashMap的源码可知，LRU算法是通过双向链表来实现，当某个位置被命中，通过调整链表的指向将该位置调整到头位置，新加入的内容直接放在链表头，如此一来，最近被命中的内容就向链表头移动，需要替换时，链表最后的位置就是最近最少使用的位置。<br />
&nbsp;&nbsp;&nbsp; LRU算法还可以通过计数来实现，缓存存储的位置附带一个计数器，当命中时将计数器加1，替换时就查找计数最小的位置并替换，结合访问时间戳来实现。这种算法比较适合缓存数据量较小的场景，显然，遍历查找计数最小位置的时间复杂度为O(n)。我实现了一个，结合了访问时间戳，当最小计数大于MINI_ACESS时(这个参数的调整对命中率有较大影响），就移除最久没有被访问的项：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;net.rubyeye.codelib.util.concurrency.cache;<br />
<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.Serializable;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.ArrayList;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Collection;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.HashMap;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Iterator;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Map;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Set;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.atomic.AtomicInteger;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.atomic.AtomicLong;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.Lock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReadWriteLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantReadWriteLock;<br />
<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@author</span><span style="color: #008000;">&nbsp;dennis&nbsp;类说明：当缓存数目不多时，才用缓存计数的传统LRU算法<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;K&gt;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;V&gt;<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;LRUCache</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;DEFAULT_CAPACITY&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">100</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;map;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;ReadWriteLock&nbsp;lock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReentrantReadWriteLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;readLock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lock.readLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;writeLock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lock.writeLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;"> </span><span style="color: #0000ff;">volatile</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity;&nbsp; //保持可见性<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;MINI_ACCESS&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">5</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRUCache()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">(DEFAULT_CAPACITY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRUCache(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;capacity)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(capacity&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;RuntimeException(</span><span style="color: #000000;">"</span><span style="color: #000000;">缓存容量不得小于0</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.maxCapacity&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;capacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(maxCapacity);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;ContainsKey(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map.containsKey(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;put(K&nbsp;key,&nbsp;V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;((map.size()&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;maxCapacity&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">map.containsKey(key))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;System.out.println("开始");</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;entries&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map.entrySet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeRencentlyLeastAccess(entries);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;new_value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ValueEntry(value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;old_value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.put(key,&nbsp;new_value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(old_value&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_value.count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;old_value.count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;old_value.value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;移除最近最少访问<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;removeRencentlyLeastAccess(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;entries)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;最小使用次数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;访问时间最早</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;it&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;entries.iterator();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(it.hasNext())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().lastAccess.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(it.hasNext())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry.getValue().count.get()&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;least)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry.getValue().lastAccess.get()&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;earliest)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;System.out.println("remove:"&nbsp;+&nbsp;toBeRemoved);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果最少使用次数大于MINI_ACCESS，那么移除访问时间最早的项(也就是最久没有被访问的项）</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(least&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;MINI_ACCESS)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.remove(toBeRemovedByTime);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.remove(toBeRemovedByCount);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;get(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;V&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;更新访问时间戳</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;valueEntry.updateLastAccess();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;更新访问次数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;valueEntry.count.incrementAndGet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clear()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.clear();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;size()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;map.size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;getCount(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;valueEntry.count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Collection</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;getAll()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;keys&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.keySet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;tmp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(K&nbsp;key&nbsp;:&nbsp;keys)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(key,&nbsp;map.get(key).value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ArrayList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">(tmp.entrySet());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ValueEntry&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;V&nbsp;value;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;AtomicLong&nbsp;count;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;AtomicLong&nbsp;lastAccess;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ValueEntry(V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AtomicLong(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastAccess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AtomicLong(System.nanoTime());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;updateLastAccess()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.lastAccess.set(System.nanoTime());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--></div>
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/149645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-09-29 17:49 <a href="http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模仿st_table写的StTable类</title><link>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 18 Sep 2007 11:28:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/146234.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/146234.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/146234.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; update1:添加了remove,removeAll()方法以及getSize()方法&nbsp;&nbsp;&nbsp; update2:添加了keySet()方法用于迭代 &nbsp;  &nbsp;&nbsp;&nbsp;update3:经过测试，StTable类在存储Integer类型key时,put的速度比HashMap快了接近3倍，而...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/146234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-09-18 19:28 <a href="http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>scheme实现huffman编码的完整代码</title><link>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 23 Jul 2007 00:56:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/131788.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/131788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/131788.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 来自sicp的完整代码，包括书中给出的代码以及习题，实现了huffman树的生成、解码、编码过程，总共67行代码，同样的代码有空用java、ruby改写下，看看会有什么不同。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;symbol&nbsp;weight)<br>&nbsp;&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">leaf&nbsp;symbol&nbsp;weight))</span><span style="color: #800000;"><br></span><span style="color: #000000;">(define&nbsp;(leaf?&nbsp;object)<br>&nbsp;&nbsp;(eq?&nbsp;(car&nbsp;object)&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">leaf))</span><span style="color: #800000;"><br></span><span style="color: #000000;">(define&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;x)&nbsp;(cadr&nbsp;x))<br>(define&nbsp;(weight</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;x)&nbsp;(caddr&nbsp;x))<br>;合并最低权重的两个节点<br>(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">code</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;left&nbsp;right)<br>&nbsp;&nbsp;(list&nbsp;left&nbsp;right&nbsp;(append&nbsp;(symbols&nbsp;left)&nbsp;(symbols&nbsp;right))&nbsp;(</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;(weight&nbsp;left)&nbsp;(weight&nbsp;right))))<br>(define&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;tree)&nbsp;(car&nbsp;tree))<br>(define&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;tree)&nbsp;(cadr&nbsp;tree))<br>(define&nbsp;(symbols&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(caddr&nbsp;tree)))<br>(define&nbsp;(weight&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(weight</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cadddr&nbsp;tree)))<br>;解码<br>(define&nbsp;(decode&nbsp;bits&nbsp;tree)<br>&nbsp;&nbsp;(define&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;bits&nbsp;current</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;bits)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(choose</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;(car&nbsp;bits)&nbsp;current</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(cdr&nbsp;bits)&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(cdr&nbsp;bits)&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)))))<br>&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;bits&nbsp;tree))<br>(define&nbsp;(choose</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;bit&nbsp;branch)<br>&nbsp;&nbsp;(cond&nbsp;((</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bit&nbsp;0)&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bit&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;(display&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">bad&nbsp;bit&nbsp;--CHOOSE-BRANCH</span><span style="color: #800000;">"</span><span style="color: #000000;">))))<br>(define&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;x&nbsp;set)<br>&nbsp;&nbsp;(cond&nbsp;((null?&nbsp;set)&nbsp;(list&nbsp;x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;(weight&nbsp;x)&nbsp;(weight&nbsp;(car&nbsp;set)))&nbsp;(cons&nbsp;x&nbsp;set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(car&nbsp;set)&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;x&nbsp;(cdr&nbsp;set))))))<br>(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;pairs)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;pairs)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((pair&nbsp;(car&nbsp;pairs)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;(car&nbsp;pair)&nbsp;(cadr&nbsp;pair))&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(cdr&nbsp;pairs))))))<br><br>;编码<br>(define&nbsp;(encode&nbsp;message&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;message)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(append&nbsp;(encode</span><span style="color: #000000;">-</span><span style="color: #000000;">symbol&nbsp;(car&nbsp;message)&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(encode&nbsp;(cdr&nbsp;message)&nbsp;tree))))<br>(define&nbsp;(encode</span><span style="color: #000000;">-</span><span style="color: #000000;">symbol&nbsp;symbol&nbsp;tree)<br>&nbsp;&nbsp;(define&nbsp;(iter&nbsp;branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(memq&nbsp;symbol&nbsp;(symbols&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;0&nbsp;(iter&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(iter&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(memq&nbsp;symbol&nbsp;(symbols&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(iter&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(display&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">bad&nbsp;symbol&nbsp;--&nbsp;UNKNOWN&nbsp;SYMBOL</span><span style="color: #800000;">"</span><span style="color: #000000;">)))<br>;生成hufman树<br>(define&nbsp;(generate</span><span style="color: #000000;">-</span><span style="color: #000000;">huffman</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;pairs)<br>&nbsp;&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;pairs)))<br><br>(define&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;(cdr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(car&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">code</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;(car&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cadr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cddr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)))))</span></div>
<br><br><br><img src ="http://www.blogjava.net/killme2008/aggbug/131788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-07-23 08:56 <a href="http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sicp 2.4节小题尝试解答</title><link>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 20 Jul 2007 06:32:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/131469.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/131469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/131469.html</trackback:ping><description><![CDATA[<br>&nbsp;&nbsp;&nbsp; 这一节那是相当的有趣，抽象数据的多重表示：采用标志(tag）来区分和数据导向（data-directed）技术，稍微提了下消息传递。通过一张二维表格将类型、操作的分派机制介绍的很清楚，静态OO语言正是通过类型来决定消息的分派，而消息传递以列进行划分，每个类型都以过程来表征，也就是所谓的&#8220;智能数据对象&#8221;，两者各有优缺点。当类型增加频繁时，消息传递风格的分派更容易扩展，当操作增加频繁时，反而是显式的类型分派更为容易扩展，这一点如果有OO设计经验应该很容易体会。<br>看看习题：<br><br>习题2.73，将求导程序以数据导向方式进行修改:<br>a）题目已经说了，基于被求导表达式的类型进行分派，加法表达式或者乘法表达式都有标志来区分，而number?和variable?并没有标志进行区分，因此无法加入数据导向分派。<br>b)选择函数不变，将求导过程提取出来，根据表达式类型划分，然后用put过程安装：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">(define&nbsp;(deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">sum&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">&nbsp;var)<br>&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">sum&nbsp;(deriv&nbsp;(addend&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(deriv&nbsp;(augend&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)))<br><br>(define&nbsp;(deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">prod&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">&nbsp;var)<br>&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">sum<br>&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">product&nbsp;(multiplier&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(deriv&nbsp;(multiplicand&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var))<br>&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">product&nbsp;(deriv&nbsp;(multiplier&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(multiplicand&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">))))<br><br>(define&nbsp;(install</span><span style="color: #000000;">-</span><span style="color: #000000;">deriv</span><span style="color: #000000;">-</span><span style="color: #0000ff;">package</span><span style="color: #000000;">)<br>&nbsp;&nbsp;(put&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">deriv&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">sum)<br>&nbsp;&nbsp;(put&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">deriv&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">prod)<br>&nbsp;&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">done)</span></div>
<br>c)我没做，不过和b差不了多少<br><br>习题2.75，很简单，跟着书上来：<br>
<div style="border: 1px solid #cccccc; padding: 