﻿<?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/leekiang/category/34736.html</link><description>MDA/MDD/TDD/DDD/DDDDDDD</description><language>zh-cn</language><lastBuildDate>Wed, 05 Oct 2011 04:25:47 GMT</lastBuildDate><pubDate>Wed, 05 Oct 2011 04:25:47 GMT</pubDate><ttl>60</ttl><item><title>并发与并行</title><link>http://www.blogjava.net/leekiang/archive/2011/10/04/360008.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Tue, 04 Oct 2011 08:08:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2011/10/04/360008.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/360008.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2011/10/04/360008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/360008.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/360008.html</trackback:ping><description><![CDATA[
		<div>并发与并行</div>
		<div>并
发，英文单词是concurrent，是指逻辑上同时发生，有人做过比喻，要完成吃完三个馒头的任务，一个人可以这个馒头咬一口，那个馒头咬一口，这样交
替进行，最后吃完三个馒头，这就是并发，因为在三个馒头上同时发生了吃的行为，如果只是吃完一个接着吃另一个，这就不是并发了，是排队，三个馒头如果分给
三个人吃，这样的任务完成形式叫并行，英文单词是parallel。</div>
		<div>回到计算机概念，并发应该是单CPU时代或者单核时代的说法，这个时候CPU要同时完成多任务，只能用时间片轮转，在逻辑上同时发生，但在物理上是串行的。现在大多数计算机都是多核或者多CPU，那么现在的多任务执行方式就是物理上并行的。</div>
		<div>为了从物理上支持并发编程，CPU提供了相应的特殊指令，比如原子化的读改写，比较并交换。</div>
		<a href="/Adley/archive/2011/09/27/359613.html">并发编程的Java抽象</a>
<img src ="http://www.blogjava.net/leekiang/aggbug/360008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2011-10-04 16:08 <a href="http://www.blogjava.net/leekiang/archive/2011/10/04/360008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符集和编码方式(转)</title><link>http://www.blogjava.net/leekiang/archive/2009/10/08/297465.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Thu, 08 Oct 2009 09:55:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/10/08/297465.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/297465.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/10/08/297465.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/297465.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/297465.html</trackback:ping><description><![CDATA[搞清常用编码特性是解决字符集编码问题的基础。字符集编码的识别与转换、分析各种乱码产生的原因、编程操作各种编码字符串（例如字符数计算、截断处理）等都需要弄清楚编码的特性。 <br />了解一种字符集编码主要是要了解该编码的编码范围，编码对应的字符集（都包含哪些字符），和其他字符集编码之间的关系等。 <br />--------1. ASCII-------- <br />ASCII码是7位编码，编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。 <br />只支持ASCII码的系统会忽略每个字节的最高位，只认为低7位是有效位。HZ字符编码就是早期为了在只支持7位ASCII系统中传输中文而设计的编码。早期很多邮件系统也只支持ASCII编码，为了传输中文邮件必须使用BASE64或者其他编码方式。 <br />--------2. GB2312-------- <br />GB2312
是基于区位码设计的，区位码把编码表分为94个区，每个区对应94个位，每个字符的区号和位号组合起来就是该汉字的区位码。区位码一般用10进制数来表
示，如1601就表示16区1位，对应的字符是"啊"。在区位码的区号和位号上分别加上0xA0就得到了GB2312编码。 <br />区位码中
01-09区是符号、数字区，16-87区是汉字区，10-15和88-94是未定义的空白区。它将收录的汉字分成两级：第一级是常用汉字计3755个，
置于16-55区，按汉语拼音字母/笔形顺序排列；第二级汉字是次常用汉字计3008个，置于56-87区，按部首/笔画顺序排列。一级汉字是按照拼音排
序的，这个就可以得到某个拼音在一级汉字区位中的范围，很多根据汉字可以得到拼音的程序就是根据这个原理编写的。 <br />GB2312字符集中除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符，未收录繁体中文汉字和一些生僻字。可以用繁体汉字测试某些系统是不是只支持GB2312编码。 <br />GB2312的编码范围是0xA1A1-0x7E7E，去掉未定义的区域之后可以理解为实际编码范围是0xA1A1-0xF7FE。 <br />EUC-CN可以理解为GB2312的别名，和GB2312完全相同。 <br />区
位码更应该认为是字符集的定义，定义了所收录的字符和字符位置，而GB2312及EUC-CN是实际计算机环境中支持这种字符集的编码。HZ和ISO-
2022-CN是对应区位码字符集的另外两种编码，都是用7位编码空间来支持汉字。区位码和GB2312编码的关系有点像
Unicode和UTF-8。 <br />--------3. GBK-------- <br />GBK编码是GB2312编码的超集，向下完全兼容
GB2312，同时GBK收录了Unicode基本多文种平面中的所有CJK汉字。同
GB2312一样，GBK也支持希腊字母、日文假名字母、俄语字母等字符，但不支持韩语中的表音字符（非汉字字符）。GBK还收录了GB2312不包含的
汉字部首符号、竖排标点符号等字符。 <br />GBK的整体编码范围是为0x8140-0xFEFE，不包括低字节是0×7F的组合。高字节范围是0×81-0xFE，低字节范围是0x40-7E和0x80-0xFE。 <br />低字节是0x40-0x7E的GBK字符有一定特殊性，因为这些字符占用了ASCII码的位置，这样会给一些系统带来麻烦。 <br />有
些系统中用0x40-0x7E中的字符（如"|"）做特殊符号，在定位这些符号时又没有判断这些符号是不是属于某个
GBK字符的低字节，这样就会造成错误判断。在支持GB2312的环境下就不存在这个问题。需要注意的是支持GBK的环境中小于0x80的某个字节未必就
是ASCII符号；另外就是最好选用小于0×40的ASCII符号做一些特殊符号，这样就可以快速定位，且不用担心是某个汉字的另一半。Big5编码中也
存在相应问题。 <br />CP936和GBK的有些许差别，绝大多数情况下可以把CP936当作GBK的别名。 <br />--------4. GB18030-------- <br />GB18030编码向下兼容GBK和GB2312，兼容的含义是不仅字符兼容，而且相同字符的编码也相同。GB18030收录了所有Unicode3.1中的字符，包括中国少数民族字符，GBK不支持的韩文字符等等，也可以说是世界大多民族的文字符号都被收录在内。 <br />GBK和GB2312都是双字节等宽编码，如果算上和ASCII兼容所支持的单字节，也可以理解为是单字节和双字节混合的变长编码。GB18030编码是变长编码，有单字节、双字节和四字节三种方式。 <br />GB18030
的单字节编码范围是0x00-0x7F，完全等同与ASCII；双字节编码的范围和GBK相同，高字节是0x81-0xFE，低字节的编码范围是
0x40-0x7E和0x80-FE；四字节编码中第一、三字节的编码范围是0x81-0xFE，二、四字节是0x30-0x39。 <br />Windows
中CP936代码页使用0x80来表示欧元符号，而在GB18030编码中没有使用0x80编码位，用其他位置来表示欧元符号。这可以理解为是
GB18030向下兼容性上的一点小问题；也可以理解为0x80是CP936对GBK的扩展，而GB18030只是和GBK兼容良好。 <br />--------5. BIG5-------- <br />Big5是双字节编码，高字节编码范围是0x81-0xFE，低字节编码范围是0x40-0x7E和0xA1-0xFE。和GBK相比，少了低字节是0x80-0xA0的组合。0x8140-0xA0FE是保留区域，用于用户造字区。 <br />Big5
收录的汉字只包括繁体汉字，不包括简体汉字，一些生僻的汉字也没有收录。GBK收录的日文假名字符、俄文字符Big5也没有收录。因为Big5当中收录的
字符有限，因此有很多在Big5基础上扩展的编码，如倚天中文系统。Windows系统上使用的代码页CP950也可以理解为是对Big5的扩展，在
Big5的基础上增加了7个汉字和一些符号。Big5编码对应的字符集是GBK字符集的子集，也就是说Big5收录的字符是GBK收录字符的一部分，但相
同字符的编码不同。 <br />因为Big5也占用了ASCII的编码空间（低字节所使用的0x40-0x7E），所以Big5编码在一些环境下存在和
GBK编码相同的问题，即低字节范围为0x40-0x7E的字符有可能会被误处理，尤其是低字节是0x5C（"/"）和0x7C（"|"）的字符。可以参
考GBK一节相应说明。 <br />尽管有些区别，大多数情况下可以把CP950当作Big5的别名。 <br />--------6. ISO-8859-1-------- <br />ISO-8859-1编码是单字节编码，向下兼容ASCII，其编码范围是0x00-0xFF，0x00-0x7F之间完全和ASCII一致，0x80-0x9F之间是控制字符，0xA0-0xFF之间是文字符号。 <br />ISO-8859-1收录的字符除ASCII收录的字符外，还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号出现的比较晚，没有被收录在ISO-8859-1当中。 <br />因
为ISO-8859-1编码范围使用了单字节内的所有空间，在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之，把
其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性，MySQL数据库默认编码是Latin1就是利用了这个特性。
ASCII编码是一个7位的容器，ISO-8859-1编码是一个8位的容器。 <br />Latin1是ISO-8859-1的别名，有些环境下写作Latin-1。 <br />--------7. UCS-2和UTF-16-------- <br />Unicode
组织和ISO组织都试图定义一个超大字符集，目的是要涵盖所有语言使用的字符以及其他学科使用的一些特殊符号，这个字符集就是通用字符集
（UCS，Universal Character
Set）。这两个组织经过协调，虽然在各自发展，但定义的字符位置是完全一致的。ISO相应的标准是ISO 10646。Unicode和ISO
10646都在不断的发展过程中，所以会有不同的版本号来标明不同的发展阶段，每个Unicode版本号都能找到相对应的ISO 10646版本号。 <br />ISO
10646标准定义了一个31位的字符集。前两个字节的位置（0x0000-0xFFFD）被称为基本多语言面（Basic Multilingual
Plane,
BMP），超出两个字节的范围称作辅助语言面。BMP基本包括了所有语言中绝大多数字符，所以只要支持BMP就可以支持绝大多数场合下的应用。
Unicode 3.0对应的字符集在BMP范围内。 <br />UCS字符集为每个字符分配了一个位置，通常用"U"再加上某个字符在UCS中位置的16进制数作为这个字符的UCS表示，例如"U+0041"表示字符"A"。UCS字符U+0000到U+00FF与ISO-8859-1完全一致。 <br />UCS-
2、UTF-16是UCS字符集（或者说是Unicode字符集）实际应用中的具体编码方式。UCS-2是两个字节的等宽编码，因为只是使用了两个字节的
编码空间，所以只能对BMP中的字符做编码。UTF-16是变长编码，用两个字节对BMP内的字符编码，用4个字节对超出BMP范围的辅助平面内的字符作
编码。 <br />UCS-2不同于GBK和Big5，它是真正的等宽编码，每个字符都使用两个字节，这个特性在字符串截断和字符数计算时非常方便。 <br />UTF-16是UCS-2的超集，UTF-16编码的两字节编码方式完全和UCS-2相同，也就是说在BMP的框架内UCS-2完全等同与UTF-16。实际情况当中常常把UTF-16当作UCS-2的别名。 <br />UCS-
2和UTF-16在存储和传输时会使用两种不同的字节序，分别是big endian和little
endian（大尾和小尾）。例如"啊"（U+554A）用big endian表示就是0x554A，用little
endian表示就是0x4A55。UCS-2和UTF-16默认的字节序是big
endian方式。在传输过程中为了说明字节序需要在字节流前加上BOM（Byte order Mark），0xFEFF表示是big
endian，0xFFFE表示是little endian。UCS-2BE、UCS-2LE是实际应用中使用的编码名称，对应着big
endian和little
endian，UTF-16BE、UTF-16LE也是如此。因为默认是BE字节序，所以可以把UCS-2当做是UCS-2BE的别名。 <br />在
UCS编码中有一个叫做"ZERO WIDTH NO-BREAK
SPACE"的字符，它的编码是U+FEFF，是个没有实际意义的字符。UCS规范建议我们在传输字节流前，先传输字符"ZERO WIDTH
NO-BREAK SPACE"，如果传输的ZERO WIDTH NO-BREAK SPACE是0xFEFF就说明是big
endian，反之就是little endian。 <br />UCS-2和UTF-16也可以理解为和ASCII以及ISO-8859-1兼容，在ASCII编码或者ISO-8859-1编码的每个字节前加上0x00，就得到相应字符的UCS-2编码。 <br />UCS-2和UTF-16中会使用0x00作为某个字符编码的一部分，某些系统会把0x00当作字符串结束的标志，在处理UCS-2或UTF-16编码时会出现问题。 <br />--------8. UTF-8-------- <br />UTF-8是UCS字符集的另一种编码方式，UTF-16的每个单元是两个字节（16位），而UTF-8的每个单元是一个字节（8位）。UTF-16中用一个或两个双字节表示一个字符，UTF-8中用一个或几个单字节表示一个字符。 <br />可以认为UTF-8编码是根据一定规律从UCS-2转换得到的，从UCS-2到UTF-8之间有以下转换关系： <br />UCS-2 UTF-8 <br />U+0000 - U+007F 0xxxxxxx <br />U+0080 - U+07FF 110xxxxx 10xxxxxx <br />U+0800 - U+FFFF 1110xxxx 10xxxxxx 10xxxxxx <br />例如"啊"字的UCS-2编码是0x554A，对应的二进制是0101 0101 0100 1010，转成UTF-8编码之后的二进制是1110 0101 10 010101 10 001010，对应的十六进制是0xE5958A。 <br />UCS-
4也是一种UCS字符集的编码方式，是使用4个字节的等宽编码，可以用UCS-4来表示BMP之外的辅助面字符。UCS-2中每两个字节前再加上
0x0000就得到了BMP字符的UCS-4编码。从UCS-4到UTF-8也存在转换关系，根据这种转换关系，UTF-8最多可以使用六个字节来编码
UCS-4。 <br />根据UTF-8的生成规律和UCS字符集的特性，可以看到UTF-8具有的特性： <br />UTF-8完全和ASCII兼容，也就是说ASCII对应的字符在UTF-8中和ASCII编码完全一致。范围在0x00-0x7F之内的字符一定是ASCII字符，不可能是其他字符的一部分。GBK和Big5都存在的缺陷在UTF-8中是不存在的。 <br />大于U+007F的UCS字符，在UTF-8编码中至少是两个字节。 <br />UTF-8中的每个字符编码的首字节总在0x00-0xFD之间（不考虑UCS-4支持的情况，首字节在0x00-0xEF之间）。根据首字节就可以判断之后连续几个字节。 <br />非首字节的其他字节都在0x80-0xBF之间；0xFE和0xFF在UTF-8中没有被用到。 <br />GBK编码中的汉字字符都在UCS-2中的范围都在U+0800 - U+FFFF之间，所以每个GBK编码中的汉字字符的UTF-8编码都是3个字节。但GBK中包含的其他字符的UTF-8编码就不一定是3个字节了，如GBK中的俄文字符。 <br />在UTF-8的编码的传输过程中即使丢掉一个字节，根据编码规律也很容易定位丢掉的位置，不会影响到其他字符。在其他双字节编码中，一旦损失一个字节，就会影响到此字节之后的所有字符。从这点可以看出UTF-8编码非常适合作为传输编码！<br />出处:http://i.cn.yahoo.com/07609654986/blog/p_14/<br /><img src ="http://www.blogjava.net/leekiang/aggbug/297465.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-10-08 17:55 <a href="http://www.blogjava.net/leekiang/archive/2009/10/08/297465.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unicode和UTF-8</title><link>http://www.blogjava.net/leekiang/archive/2009/10/08/297460.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Thu, 08 Oct 2009 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/10/08/297460.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/297460.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/10/08/297460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/297460.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/297460.html</trackback:ping><description><![CDATA[
		<p>为了统一全世界各国语言文字和专业领域符号（例如数学符号、乐谱符号）的编码，ISO制定了ISO 10646标准，也称为UCS（Universal Character Set）。UCS编码的长度是31位，可以表示2<sup>31</sup>个字符。如果两个字符编码的高位相同，只有低16位不同，则它们属于一个平面（Plane），所以一个平面由2<sup>16</sup>个字符组成。目前常用的大部分字符都位于第一个平面（编码范围是U-00000000~U-0000FFFD），称为BMP（Basic Multilingual Plane）或Plane
0，为了向后兼容，其中编号为0~256的字符和Latin-1相同。UCS编码通常用U-xxxxxxxx这种形式表示，而BMP的编码通常用
U+xxxx这种形式表示，其中x是十六进制数字。在ISO制定UCS的同时，另一个由厂商联合组织也在着手制定这样的编码，称为Unicode，后来两家联手制定统一的编码，但各自发布各自的标准文档，所以UCS编码和Unicode码是相同的。</p>
		<p>有了字符编码，另一个问题就是这样的编码在计算机中怎么表示。现在已经不可能用一个字节表示一个字符了，最直接的想法就是用四个字节表示一个字符，这种表示方法称为UCS-4或UTF-32，UTF是Unicode Transformation Format的缩写。一方面这样比较浪费存储空间，由于常用字符都集中在BMP，高位的两个字节通常是0，如果只用ASCII码或Latin-1，高位的三个字节都是0。另一种比较节省存储空间的办法是用两个字节表示一个字符，称为UCS-2或UTF-16，这样只能表示BMP中的字符，但BMP中有一些扩展字符，可以用两个这样的扩展字符表示其它平面的字符，称为Surrogate Pair。无论是UTF-32还是UTF-16都有一个更严重的问题是和C语言不兼容，在C语言中0字节表示字符串结尾，库函数<code class="literal">strlen</code>、<code class="literal">strcpy</code>等等都依赖于这一点，如果字符串用UTF-32存储，其中有很多0字节并不表示字符串结尾，这就乱套了。</p>
		<p>UNIX之父Ken Thompson提出的UTF-8编码很好地解决了这些问题，现在得到广泛应用。UTF-8具有以下性质：</p>
		<div class="itemizedlist">
				<ul type="disc">
						<li>
								<p>编码为U+0000~U+007F的字符只占一个字节，就是0x00~0x7F，和ASCII码兼容。</p>
						</li>
						<li>
								<p>编码大于U+007F的字符用2~6个字节表示，每个字节的最高位都是1，而ASCII码的最高位都是0，因此非ASCII码字符的表示中不会出现ASCII码字节（也就不会出现0字节）。</p>
						</li>
						<li>
								<p>用于表示非ASCII码字符的多字节序列中，第一个字节的取值范围是0xC0~0xFD，根据它可以判断后面有多少个字节也属于当前字符的编码。后面每个字节的取值范围都是0x80~0xBF，见下面的详细说明。</p>
						</li>
						<li>
								<p>UCS定义的所有2<sup>31</sup>个字符都可以用UTF-8编码表示出来。</p>
						</li>
						<li>
								<p>UTF-8编码最长6个字节，BMP字符的UTF-8编码最长三个字节。</p>
						</li>
						<li>
								<p>0xFE和0xFF这两个字节在UTF-8编码中不会出现。</p>
						</li>
				</ul>
		</div>
		<p>具体来说，UTF-8编码有以下几种格式：</p>
		<div class="literallayout">
				<p>U-00000000 – U-0000007F: 	0xxxxxxx<br />
U-00000080 – U-000007FF: 	110xxxxx 10xxxxxx<br />
U-00000800 – U-0000FFFF: 	1110xxxx 10xxxxxx 10xxxxxx<br />
U-00010000 – U-001FFFFF: 	11110xxx 10xxxxxx 10xxxxxx 10xxxxxx<br />
U-00200000 – U-03FFFFFF: 	111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx<br />
U-04000000 – U-7FFFFFFF: 	1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx</p>
		</div>
		<p>第
一个字节要么最高位是0（ASCII字节），要么最高两位都是1，最高位之后1的个数决定后面有多少个字节也属于当前字符编码，例如111110xx，最
高位之后还有四个1，表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10，可以和第一个字节区分开。这样的设计有利于误码同步，例
如在网络传输过程中丢失了几个字节，很容易判断当前字符是不完整的，也很容易找到下一个字符从哪里开始，结果顶多丢掉一两个字符，而不会导致后面的编码解
释全部混乱了。上面的格式中标为x的位就是UCS编码，最后一种6字节的格式中x位有31个，可以表示31位的UCS编码，UTF-8就像一列火车，第一
个字节是车头，后面每个字节是车厢，其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示，也就是说第一个字节中的x是UCS编码的高
位，后面字节中的x是UCS编码的低位。</p>
		<p>例如U+00A9（©字符）的二进制是10101001，编码成UTF-8是11000010 10101001（0xC2 0xA9），但不能编码成11100000 10000010 10101001，UTF-8规定每个字符只能用尽可能少的字节来编码。</p>
		<p>来源:http://learn.akae.cn/media/apas02.html<br /></p>
<img src ="http://www.blogjava.net/leekiang/aggbug/297460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-10-08 17:31 <a href="http://www.blogjava.net/leekiang/archive/2009/10/08/297460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>排列组合、随机</title><link>http://www.blogjava.net/leekiang/archive/2009/10/04/297215.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Sun, 04 Oct 2009 11:17:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/10/04/297215.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/297215.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/10/04/297215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/297215.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/297215.html</trackback:ping><description><![CDATA[
		<a target="_blank" href="http://javahy.javaeye.com/blog/384808">解决排列组合问题的通用算法</a>
		<br />
		<a href="http://www.bugcode.com/diary/9597">JAVA实现排列组合算法</a>
		<br />
		<a href="http://www.java-cn.com/club/html/12/n-512.html">浅析实现排列组合查询算法</a>
		<br />
		<a href="http://www.java-cn.com/club/html/39/n-339.html">关于Java权限控制算法</a>
		<br />
		<br />
		<br />随机<br />从0,1,2三个数字中随机取一个:<br />int n = (int) (Math.random() * 3);//Math.random()返回的double值&gt;=0且&lt;1<br />注意不能使用long l=(Math.round(Math.random()*2)，因为这样三个数字的机率分别是25%,50%,25%,不是均匀分布的。<br />也可以使用Random rand = new Random();int n = rand.nextInt(3);的方式产生，但后者的结果明显没有Math.random()的方式那么均匀，只是后者会稍微快一些(可忽略不计)。<br /><br />M到N的随机整数：<br />(int)(M+(N-M)*Math.random()) <br /><img src ="http://www.blogjava.net/leekiang/aggbug/297215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-10-04 19:17 <a href="http://www.blogjava.net/leekiang/archive/2009/10/04/297215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>算法与数据结构</title><link>http://www.blogjava.net/leekiang/archive/2009/08/17/291399.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Sun, 16 Aug 2009 19:28:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/08/17/291399.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/291399.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/08/17/291399.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/291399.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/291399.html</trackback:ping><description><![CDATA[http://topic.csdn.net/u/20090811/10/9c233a7f-ab58-4e5f-8ff9-7060715f7c0a_3.html<br />不可能都完全记住那么多的算法. <br /> 常用算法,拿过来就可以写出来 <br /> 不常用的,拿起书来,看10分钟,就能理解算法(因为以前记过). <br /> 对以前没有记过的算法,就不好说了,难的可能要研究好几天. <br /> 这样就可以了. <br /><br /> 应该熟练掌握的常用的算法应该有: <br /> 各种排序算法（插入排序、冒泡排序、选择排序，快速排序，堆排序，归并排序） <br /> 线性表(一般的线性表,栈,队列)的插入和删除 <br /> 二叉树的遍历（前序，中序，后序） <br /> 图的遍历（深度优先，广度优先） <br /> 二分法查找，排序二叉树，Hash查找（处理冲突的方法）。 <br /><br /><br />对于更深层次的东西，也是建立在自己熟练的基础之上的吧<br /><br />《算法与数据结构考研试题精析》第2版 机械工业出版社 <br /> 如果你想练习的话，这里有N多的题可以来练习，但实际中能用到的比较少，除非搞一些高端的玩意，不过平时也可以在自己的项目中结合使用<br /><br /><pre>最重要的就是操作系统了(个人认为此乃计算机的精髓所在,一通百通)<br /><br />转一个搞ACM需要的掌握的算法. <br /> 要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来. <br /> 适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什么就眼红, <br /> 发挥自己的长处,这才是重要的. <br /><br /><br /> 第一阶段：练经典常用算法，下面的每个算法给我打上十到二十遍，同时自己精简代码， <br /> 因为太常用，所以要练到写时不用想，10-15分钟内打完，甚至关掉显示器都可以把程序打 <br /> 出来.  <br /> 1.最短路(Floyd、Dijstra,BellmanFord)  <br /> 2.最小生成树(先写个prim,kruscal要用并查集，不好写)  <br /> 3.大数（高精度）加减乘除  <br /> 4.二分查找. (代码可在五行以内)  <br /> 5.叉乘、判线段相交、然后写个凸包.  <br /> 6.BFS、DFS,同时熟练hash表(要熟，要灵活,代码要简)  <br /> 7.数学上的有：辗转相除（两行内），线段交点、多角形面积公式.  <br /> 8. 调用系统的qsort, 技巧很多，慢慢掌握.  <br /> 9. 任意进制间的转换 <br /><br /> 第二阶段：练习复杂一点，但也较常用的算法。  <br /> 如：  <br /> 1. 二分图匹配（匈牙利），最小路径覆盖  <br /> 2. 网络流，最小费用流。  <br /> 3. 线段树.  <br /> 4. 并查集。  <br /> 5. 熟悉动态规划的各个典型：LCS、最长递增子串、三角剖分、记忆化dp  <br /> 6.博弈类算法。博弈树，二进制法等。  <br /> 7.最大团，最大独立集。  <br /> 8.判断点在多边形内。  <br /> 9. 差分约束系统.  <br /> 10. 双向广度搜索、A*算法，最小耗散优先. <br /><br /><br /> 相关的知识 <br /><br /> 图论 <br /><br />    路径问题 <br />         0/1边权最短路径 <br />         BFS <br />         非负边权最短路径（Dijkstra） <br />             可以用Dijkstra解决问题的特征 <br />         负边权最短路径 <br />         Bellman-Ford <br />             Bellman-Ford的Yen-氏优化 <br />             差分约束系统 <br />         Floyd <br />             广义路径问题 <br />             传递闭包 <br />             极小极大距离 / 极大极小距离 <br />         Euler Path / Tour <br />             圈套圈算法 <br />             混合图的 Euler Path / Tour <br />         Hamilton Path / Tour <br />             特殊图的Hamilton Path / Tour 构造 <br /><br />     生成树问题 <br />         最小生成树 <br />         第k小生成树 <br />         最优比率生成树 <br />         0/1分数规划 <br />         度限制生成树 <br /><br />     连通性问题 <br />         强大的DFS算法 <br />         无向图连通性 <br />             割点 <br />             割边 <br />             二连通分支 <br />             有向图连通性 <br />             强连通分支 <br />             2-SAT <br />             最小点基 <br /><br />     有向无环图 <br />         拓扑排序 <br />             有向无环图与动态规划的关系 <br /><br />     二分图匹配问题 <br />         一般图问题与二分图问题的转换思路 <br />         最大匹配 <br />             有向图的最小路径覆盖 <br />             0 / 1矩阵的最小覆盖 <br />         完备匹配 <br />         最优匹配 <br />         稳定婚姻 <br /><br />     网络流问题 <br />         网络流模型的简单特征和与线性规划的关系 <br />         最大流最小割定理 <br />         最大流问题 <br />             有上下界的最大流问题 <br />                 循环流 <br />         最小费用最大流 / 最大费用最大流 <br /><br />     弦图的性质和判定 <br /><br /><br /> 组合数学 <br /><br />     解决组合数学问题时常用的思想 <br />         逼近 <br />         递推 / 动态规划 <br />     概率问题 <br />         Polya定理 <br /><br /><br /> 计算几何 / 解析几何 <br /><br />     计算几何的核心：叉积 / 面积 <br />     解析几何的主力：复数 <br /><br />     基本形 <br />         点 <br />         直线，线段 <br />         多边形 <br /><br />     凸多边形 / 凸包 <br />         凸包算法的引进，卷包裹法 <br /><br />     Graham扫描法 <br />         水平序的引进，共线凸包的补丁 <br /><br />     完美凸包算法 <br /><br />     相关判定 <br />         两直线相交 <br />         两线段相交 <br />         点在任意多边形内的判定 <br />         点在凸多边形内的判定 <br /><br />     经典问题 <br />         最小外接圆 <br />             近似O(n)的最小外接圆算法 <br />         点集直径 <br />             旋转卡壳，对踵点 <br />         多边形的三角剖分 <br /><br /><br /> 数学 / 数论 <br /><br />    最大公约数 <br />         Euclid算法 <br />             扩展的Euclid算法 <br />                 同余方程 / 二元一次不定方程 <br />                 同余方程组 <br /><br />     线性方程组 <br />         高斯消元法 <br />             解mod 2域上的线性方程组 <br />         整系数方程组的精确解法 <br /><br />     矩阵 <br />         行列式的计算 <br />             利用矩阵乘法快速计算递推关系 <br /><br />     分数 <br />         分数树 <br />         连分数逼近 <br /><br />     数论计算 <br />         求N的约数个数 <br />         求phi(N) <br />         求约数和 <br />         快速数论变换 <br />         …… <br /><br />     素数问题 <br />         概率判素算法 <br />         概率因子分解 <br /><br /><br /> 数据结构 <br /><br />     组织结构 <br />         二叉堆 <br />         左偏树 <br />         二项树 <br />         胜者树 <br />         跳跃表 <br />         样式图标 <br />         斜堆 <br />         reap <br /><br />     统计结构 <br />         树状数组 <br />         虚二叉树 <br />         线段树 <br />             矩形面积并 <br />             圆形面积并 <br /><br />     关系结构 <br />         Hash表 <br />         并查集 <br />             路径压缩思想的应用 <br /><br />     STL中的数据结构 <br />         vector <br />         deque <br />         set / map <br /><br /><br /> 动态规划 / 记忆化搜索 <br /><br />    动态规划和记忆化搜索在思考方式上的区别 <br /><br />     最长子序列系列问题 <br />         最长不下降子序列 <br />         最长公共子序列 <br />         最长公共不下降子序列 <br /><br />     一类NP问题的动态规划解法 <br /><br />     树型动态规划 <br /><br />     背包问题 <br /><br />     动态规划的优化 <br />         四边形不等式 <br />         函数的凸凹性 <br />         状态设计 <br />         规划方向 <br /><br /><br /> 线性规划 <br /><br /> 常用思想 <br /><br />     二分           最小表示法 <br /><br /> 串 <br /><br />     KMP                              Trie结构 <br />     后缀树/后缀数组            LCA/RMQ <br />     有限状态自动机理论 <br /><br /> 排序 <br />     选择/冒泡        快速排序         堆排序             归并排序 <br />     基数排序         拓扑排序        排序网络 <br /><br /><br /> 中级:  <br /> 一.基本算法:  <br />      (1)C++的标准模版库的应用. (poj3096,poj3007)  <br />      (2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)  <br /> 二.图算法:  <br />      (1)差分约束系统的建立和求解. (poj1201,poj2983)  <br />      (2)最小费用最大流(poj2516,poj2516,poj2195)  <br />      (3)双连通分量(poj2942)  <br />      (4)强连通分支及其缩点.(poj2186)  <br />      (5)图的割边和割点(poj3352)  <br />      (6)最小割模型、网络流规约(poj3308, )  <br /> 三.数据结构.  <br />      (1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)  <br />      (2)静态二叉检索树. (poj2482,poj2352)  <br />      (3)树状树组(poj1195,poj3321)  <br />      (4)RMQ. (poj3264,poj3368)  <br />      (5)并查集的高级应用. (poj1703,2492)  <br />      (6)KMP算法. (poj1961,poj2406)  <br /> 四.搜索  <br />      (1)最优化剪枝和可行性剪枝  <br />      (2)搜索的技巧和优化 (poj3411,poj1724)  <br />      (3)记忆化搜索(poj3373,poj1691)  <br />        <br /> 五.动态规划  <br />      (1)较为复杂的动态规划(如动态规划解特别的施行商问题等)  <br />          (poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)  <br />      (2)记录状态的动态规划. (POJ3254,poj2411,poj1185)  <br />      (3)树型动态规划(poj2057,poj1947,poj2486,poj3140)  <br /> 六.数学  <br />      (1)组合数学:  <br />         1.容斥原理.  <br />         2.抽屉原理.  <br />         3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).  <br />         4.递推关系和母函数.  <br />           <br />      (2)数学.  <br />         1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)  <br />         2.概率问题. (poj3071,poj3440)  <br />         3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)  <br />      (3)计算方法.  <br />         1.0/1分数规划. (poj2976)  <br />         2.三分法求解单峰(单谷)的极值.  <br />         3.矩阵法(poj3150,poj3422,poj3070)  <br />         4.迭代逼近(poj3301)  <br />      (4)随机化算法(poj3318,poj2454)  <br />      (5)杂题.  <br />          (poj1870,poj3296,poj3286,poj1095)  <br /> 七.计算几何学.  <br />         (1)坐标离散化.  <br />         (2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).  <br />             (poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)  <br />         (3)多边形的内核(半平面交)(poj3130,poj3335)  <br />         (4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429) <br /><br /><br /> 高级:  <br /> 一.基本算法要求:    <br />       (1)代码快速写成,精简但不失风格    <br />           (poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)  <br />       (2)保证正确性和高效性. poj3434  <br /> 二.图算法:  <br />       (1)度限制最小生成树和第K最短路. (poj1639)  <br />       (2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)  <br />          (poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446  <br />       (3)最优比率生成树. (poj2728)  <br />       (4)最小树形图(poj3164)  <br />       (5)次小生成树.  <br />       (6)无向图、有向图的最小环     <br /> 三.数据结构.    <br />       (1)trie图的建立和应用. (poj2778)  <br />       (2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法  <br />           (RMQ+dfs)).(poj1330)  <br />       (3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的  <br />           目的). (poj2823)  <br />       (4)左偏树(可合并堆).    <br />       (5)后缀树(非常有用的数据结构,也是赛区考题的热点).  <br />          (poj3415,poj3294)  <br /> 四.搜索    <br />       (1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)  <br />       (2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)  <br />       (3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)  <br /> 五.动态规划    <br />       (1)需要用数据结构优化的动态规划.  <br />          (poj2754,poj3378,poj3017)  <br />       (2)四边形不等式理论.  <br />       (3)较难的状态DP(poj3133)  <br /> 六.数学    <br />       (1)组合数学.  <br />         1.MoBius反演(poj2888,poj2154)  <br />         2.偏序关系理论.  <br />       (2)博奕论.  <br />         1.极大极小过程(poj3317,poj1085)  <br />         2.Nim问题.  <br /> 七.计算几何学.    <br />       (1)半平面求交(poj3384,poj2540)  <br />       (2)可视图的建立(poj2966)  <br />       (3)点集最小圆覆盖.  <br />       (4)对踵点(poj2079)  <br />       八.综合题.  <br />       (poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263) <br /><br /> 初期:  <br /> 一.基本算法:  <br />      (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586)  <br />      (3)递归和分治法.                  (4)递推.  <br />      (5)构造法.(poj3295)             (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)  <br /> 二.图算法:  <br />      (1)图的深度优先遍历和广度优先遍历.  <br />      (2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)  <br />         (poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)  <br />      (3)最小生成树算法(prim,kruskal)  <br />         (poj1789,poj2485,poj1258,poj3026)  <br />      (4)拓扑排序 (poj1094)  <br />      (5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)  <br />      (6)最大流的增广路算法(KM算法). (poj1459,poj3436)  <br /> 三.数据结构.  <br />      (1)串 (poj1035,poj3080,poj1936)  <br />      (2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)  <br />      (3)简单并查集的应用.  <br />      (4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)     <br />         (poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)  <br />      (5)哈夫曼树(poj3253)  <br />      (6)堆  <br />      (7)trie树(静态建树、动态建树) (poj2513)  <br /> 四.简单搜索  <br />      (1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)  <br />      (2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)  <br />      (3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)  <br /> 五.动态规划  <br />      (1)背包问题. (poj1837,poj1276)  <br />      (2)型如下表的简单DP(可参考lrj的书 page149):  <br />        1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)  <br />        2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)      <br />          (poj3176,poj1080,poj1159)  <br />        3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)  <br /> 六.数学  <br />      (1)组合数学:  <br />         1.加法原理和乘法原理.  <br />         2.排列组合.  <br />         3.递推关系.  <br />           (POJ3252,poj1850,poj1019,poj1942)  <br />      (2)数论.  <br />         1.素数与整除问题  <br />         2.进制位.  <br />         3.同余模运算.  <br />           (poj2635, poj3292,poj1845,poj2115)  <br />      (3)计算方法.  <br />         1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)  <br /> 七.计算几何学.  <br />      (1)几何公式.  <br />      (2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)  <br />      (3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)  <br />          (poj1408,poj1584)  <br />      (4)凸包. (poj2187,poj1113)  <br /><br />我给你推荐一本书，我就是看了这本书而得到了很大的提升，就是数据结构与抽象JAVA版，我买的是2004年的第一版，还没有找到别的版的，里面基本上讲<br />的全是数据结构还有数据结构中实现的算法，非常好的一本教程，绝对精典。有很多数据结果与算法的书里讲了很多数学的算法那个对于我们来说基本上看不懂，而<br /><br />算法这种东西 关键是你了解多少 而不是你会多少，所以学了忘记你也不用怕。 <br /> 为了学算法而去学算法到头就是一场空,对自己算法没底的,建议先看下java中的各种工具容器的源码,查看 <br /> 下java对算法是如何用的,然后再去查这些算法的优缺点,和大致流程。在以后用java工具容器的时候你能清楚的知道在什么地方用什么东西 这就足够了。java玩到后面对框架整体把握才是王道 算法都是拿来主义就行了。 <br /><br />常用的算法记住一些，不常用的算法经常看看，有时候是需要的时候才会去看一下算法方面的，因为有时候可以自己想着一些法子来做算法方面的编程，如果大家都<br />是一个样子出来的东西也就没什么创新的东西。创新能力才是最重要的能力。知识呈现爆炸型发展，不可能有那么多的精力去学习那么多东西的。如果真能记住那么<br /><br />个人感觉，所谓程序算法，就是解决问题一种思路、想法。你了解一种算法，也只是了解了一种解决问题的思路，而更为重要的是你要把这种解决问题的思想融入自<br />己的思想，从而用这个思想来解决今后相似的问题。而在这个过程之中，需要的就是思考，要完整而全面地思考算法的思想与你原始思想之间的异同点，要完全消化<br />这种算法的思想。这就如小说中的人物，他再NB，也没有写小说的作者NB啊。<br />多的算法那也可以去记住，拿过来用就好了。<br />且用的也很少。<br /></pre><br /><img src ="http://www.blogjava.net/leekiang/aggbug/291399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-08-17 03:28 <a href="http://www.blogjava.net/leekiang/archive/2009/08/17/291399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>树</title><link>http://www.blogjava.net/leekiang/archive/2008/09/20/230053.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Fri, 19 Sep 2008 17:54:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2008/09/20/230053.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/230053.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2008/09/20/230053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/230053.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/230053.html</trackback:ping><description><![CDATA[1,B 树、 B- 树、 B+ 树、 B* 树都是什么<br />
http://www.cppblog.com/qiujian5628/articles/42190.html<br /><br />
2,红黑树<br />
http://baike.baidu.com/view/133754.htm<br /><br />3,AVL树<br />http://zh.wikipedia.org/wiki/AVL%E6%A0%91<br /><br />4,分析代码的时空复杂度（图n最短路径算法）<br /><span style="color: red;"></span><img src ="http://www.blogjava.net/leekiang/aggbug/230053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2008-09-20 01:54 <a href="http://www.blogjava.net/leekiang/archive/2008/09/20/230053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>