??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩精彩视频,免费黄网站在线观看,中文视频一区http://www.aygfsteel.com/jeff-lau/category/28232.html我的宇宙要爆发?-急啊zh-cnSat, 22 Dec 2007 00:28:25 GMTSat, 22 Dec 2007 00:28:25 GMT60中文数字http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169466.htmlJeff LauJeff LauFri, 21 Dec 2007 15:09:00 GMThttp://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169466.htmlhttp://www.aygfsteel.com/jeff-lau/comments/169466.htmlhttp://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169466.html#Feedback0http://www.aygfsteel.com/jeff-lau/comments/commentRss/169466.htmlhttp://www.aygfsteel.com/jeff-lau/services/trackbacks/169466.html摘要Q以中文的Ş式表C数字,在开具发、收据的时候经常用刎ͼ其在金融领域。但数字的中文表C和其它语言有很大的不同Q如中文以每4个数??Z个小的分隔?本文以测试驱动开发的Ҏ(gu)Q开发该功能。本E序只是用表C整数的中文形式Q很Ҏ(gu)扩展到l(f)ong形式和表CZh民币货币的表CŞ式?/p>

作者:Jeff 发表于:2006-12-02 08:12 最后更CQ?2007q?2?1?23:10
版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本版权声?/a>?br>http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169466.html


/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.test;

import org.junit.Assert;
import org.junit.Test;

import chinese.utility.ChineseNumber;

public class ChinesNumberFormatter {

    /**
     * 单个数字 0--9
     */
    @Test
    public void testSingleLower() {
        Assert.assertEquals("?, new ChineseNumber(0).lower());
        Assert.assertEquals("?, new ChineseNumber(5).lower());
    }
    /**
     * 10--99
     */
    @Test
    public void test2BitLower() {
        Assert.assertEquals("六十?, new ChineseNumber(68).lower());
        Assert.assertEquals("八十", new ChineseNumber(80).lower());
    }

    /**
     * 100--999
     */
    @Test
    public void test3BitLower() {
        Assert.assertEquals("五百零八", new ChineseNumber(508).lower());
        Assert.assertEquals("八百", new ChineseNumber(800).lower());       
    }

    /**
     * 1000--9999
     */
    @Test
    public void test4BitLower() {
        Assert.assertEquals("一千零?, new ChineseNumber(1008).lower());
        Assert.assertEquals("一千零八十", new ChineseNumber(1080).lower());

    }
    /**
     * > 9999
     */
    @Test
    public void test5BitLower() {
        Assert.assertEquals("三十万零八千", new ChineseNumber(308000).lower());
        Assert.assertEquals("三十万零八百", new ChineseNumber(300800).lower());
    }
    /**
     * ~写和大写一h
     */
    @Test
    public void testAbbriation() {
        Assert.assertEquals("拾捌", new ChineseNumber(18, true).upper());
    }

}

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility;

public class ChineseNumber {

    private static final int RADIX = 10;

    private static final String[] LOWER_UNIT = { "", "?, "?, "?, "?, "?,
            "?, "?, "?, "?, "?, "?, "?, "?, "?, "?, "? };
    private String[] LOWER = { "?, "一", "?, "?, "?, "?, "?, "?, "?, "? };

    private static final String[] UPPER_UNIT = { "", "?, "?, "?, "?, "?,
            "?, "?, "?, "?, "?, "?, "?, "?, "?, "?, "? };
    private String[] UPPER = { "?, "?, "?, "?, "?, "?, "?, "?, "?, "? };

    private int number;
    private boolean abbreviation;

    public ChineseNumber(int number, boolean isShort) {
        this.number = number;
        this.abbreviation = isShort;
    }

    public ChineseNumber(int number) {
        this(number, false);
    }

    public String lower() {
        return format(LOWER, LOWER_UNIT);
    }
    public String upper() {   
        return format(UPPER, UPPER_UNIT);
    }
    private String format(final String[] chinese, final String[] unit) {
        if (number == 0) {
            return chinese[number];
        }

        if (abbreviation == true && canAbbreviate(number)) {
            return formatShort(chinese, unit);
        }
        String result = "";

        int leftNumber = number;
        int rightNumber = 0;
        int currentNumber = 0;
        int bit = 0;
        while (leftNumber > 0) {
            rightNumber = currentNumber;
            currentNumber = leftNumber % RADIX;
            leftNumber = leftNumber / RADIX;

            if (currentNumber > 0) {
                result = chinese[currentNumber] + unit[bit] + result;
            } else if (rightNumber > 0) {
                result = chinese[currentNumber] + result;
            }

            if (bit % 4 == 0 && currentNumber == 0) {
                result = unit[bit] + result;
            }

            bit++;
        }

        return result;

    }

    /**
     * ~写 18 ?十八 ?拾捌
     */
    private String formatShort(String[] chinese, String[] unit) {       
        return unit[1] + chinese[number % RADIX];
    }

    /**
     * 能否~写
     */
    private boolean canAbbreviate(int number2) {
        if (number2 >= 9 && number2 <= 19) {
            return true;
        }
        return false;
    }

}



Jeff Lau 2007-12-21 23:09 发表评论
]]>
中文排序http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.htmlJeff LauJeff LauFri, 21 Dec 2007 03:29:00 GMThttp://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.htmlhttp://www.aygfsteel.com/jeff-lau/comments/169257.htmlhttp://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html#Feedback1http://www.aygfsteel.com/jeff-lau/comments/commentRss/169257.htmlhttp://www.aygfsteel.com/jeff-lau/services/trackbacks/169257.html摘要Q在Java中,对一个数l或列表(在本文中l称为集?中的元素排序Q是一个很l常的事情。好在Sun公司在Java库中实现了大部分功能。如果集合中的元素实CComparable接口Q调用Array或Collections的静?static)Ҏ(gu)sortQ就可以直接寚w合排序。程序员用不同的方式实现了Comparator接口Q就可以用各自不同的方式排序。对于包含汉字的字符串来_排序的方式主要有两种Q一U是拼音Q一U是W画。本文就讲述如何实现q两U不同的比较?Comparator)?/p>

作者:Jeff 发表于:2007q?2?1?11:27 最后更CQ?2007q?2?1?12:38
版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本版权声?/a>?br>http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html


排序概述

在Java中,对一个数l或列表(在本文中l称为集?中的元素排序Q是一个很l常的事情。好在Sun公司在Java库中实现了大部分功能。如果集合中的元素实CComparable接口Q调用以下的静?static)Ҏ(gu)Q就可以直接寚w合排序?/p>

// 数组排序Ҏ(gu)
// 数组中的元素可以是像intq样的原生类?primitive type), 也可以是像Stringq样实现了Comparable接口的类型,q里用type表示?
java.util.Arrays.sort(type[] a);

// 列表
public static <T> void sort(List<T> list)

以上的这些排序方式能满大部分应用。但集合中的元素没有实现Comparable接口Q或者集合中的元素要按一U特别的方式排序Q这要怎么办?Sun公司早就惛_了,q在Java库中提供上面两个Ҏ(gu)的重载?/p>

// 数组排序Ҏ(gu)?br>// 数组中的元素可以是像intq样的原生类?primitive type), 也可以是像Stringq样实现了Comparable接口的类型,q里用type表示?
public static <T> void sort(T[] a, Comparator<? super T> c)

// 列表
public static <T> void sort(List<T> list, Comparator<? super T> c)

只要实现了Comparator接口Q就可以按程序员自己的意思去排序了。对于包含汉字的字符串来_排序的方式主要有两种Q一U是拼音Q一U是W画。汉字是通过一定的~码方式存储在计机上的Q主要的~码有:Unicdoe、GB2312和GBK{?/p>

Unicode ~码中的汉字

Unicode中编码表分ؓ两块Q一个是基本的,一个是辅助的。现在的大多数操作系l还不支持Unicode中辅助区域中的文字,如WinXp?/p>

在Java中的字符是Unicode码表C的。对于Unicode基本区域中的文字Q用两个字节的内存存储,用一个char表示Q而辅助区域中的文字用4个字节存储,因此辅助区域中的p用两个char来表CZ(表一U蓝色底是辅助区域中的文字)。一个文字的unicode~码Q在Java中统一用codePoint(代码?q个概念?/p>

中文和日文、韩文一h表意文字Q在Unicode中,中日韩三?东亚地区)的文字是l一~码的。CJK代表的就是中日韩。在q里Q我把这3中文字,都作为汉字处理了?日语和韩语可能就是从汉语中衍生的吧!)

汉字在Unicode中的分布大致如下表:

  首字~码 ֭~码 个数
基本汉字 U4E00 U9FBF 20928
异性字 UF900 UFAFF 512
扩展A U3400 U4D8F 512
扩展B U20000 U2A6DF 42720
补充 U2F800 U2FA1F 544
其他     ...
表一

在这些编码区_有些~码是保留的?/p>

GB2312~码

GB2312是中华h民共和国最早的计算机汉字编码方式。大概有6000多个汉字Q这些汉字是按拼音顺序编码的。这6000多个汉字都是体中文字?/p>

GBK~码

GB2312的扩展,q兼容GB2312。扩展后的汉字大概有2万多个,其中有简体汉字也有繁体汉字?/p>

拼音排序

拼音有好几种方式Q其中最主要的是中华人民共和国的汉语拼音 Chinese Phonetic。对汉字的排序有两种Q一U是宽松的,能够按拼x序最常用的汉字,另一U是严格的,能够按拼x序绝大部分大部分汉字?/p>

宽松的拼x序法

原理Q汉字最早是GB2312~码Q收录了六千多个汉字Q是按拼x序的Q编码是q箋的?后来出现了GBK~码Q对GB2312q行了扩展,C两万多汉字,q且兼容GB2312Q也是说GB2312中的汉字~码是原不动搬到GBK中的(在GBK~码中[B0-D7]Z)?/p>

如果我们只关心这6000多个汉字的顺序,可以用下面的方法实现汉字宽松排序?/p>

/**
* @author Jeff
*
* Copyright (c) 复制或{载本文,请保留该注释?br>*/

package chinese.utility;

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;

public class PinyinSimpleComparator implements Comparator<String> {
    public int compare(String o1, String o2) {
        return Collator.getInstance(Locale.CHINESE).compare(o1, o2);
    }
}

在对[? ? ? ? ? ? ? ? ? ?怡]q几个汉字排序,l果是:[? ? ? ? ? ? ? ? ? ? 怡]。最后一?strong> ?/strong> 有问题,不该排在最后的?

注意Q这个程序有两个不

  • ׃gb2312中的汉字~码是连l的Q因此新增加的汉字不可能再按照拼音顺序插入到已有的gb2312~码中,所以新增加的汉字不是按拼音序排的?
  • 同音字比较的l果不等? ?

下面的测试代码可以证?/p>

/**
* @author Jeff
*
* Copyright (c) 复制或{载本文,请保留该注释?br>*/

/**
* 非常用字(?
*/
@Test
public void testNoneCommon() {
    Assert.assertTrue(comparator.compare("?, "?) > 0);
}

/**
* 同音?br>*/
@Test
public void testSameSound() {
    Assert.assertTrue(comparator.compare("?, "?) != 0);
}

严格的拼x序法

Z解决宽松的拼音的两点不Q可以通过实现汉语拼音的函数来解决。goolge下看到sf上有个pinyin4j的项目,可以解决q个问题Qpinyin4j的项目地址是:http://pinyin4j.sourceforge.net/?/p>

实现代码Q?/p>

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility;

import java.util.Comparator;
import net.sourceforge.pinyin4j.PinyinHelper;

public class PinyinComparator implements Comparator<String> {

    public int compare(String o1, String o2) {

        for (int i = 0; i < o1.length() && i < o2.length(); i++) {

            int codePoint1 = o1.charAt(i);
            int codePoint2 = o2.charAt(i);

            if (Character.isSupplementaryCodePoint(codePoint1)
                    || Character.isSupplementaryCodePoint(codePoint2)) {
                i++;
            }

            if (codePoint1 != codePoint2) {
                if (Character.isSupplementaryCodePoint(codePoint1)
                        || Character.isSupplementaryCodePoint(codePoint2)) {
                    return codePoint1 - codePoint2;
                }

                String pinyin1 = pinyin((char) codePoint1);
                String pinyin2 = pinyin((char) codePoint2);

                if (pinyin1 != null && pinyin2 != null) { // 两个字符都是汉字
                    if (!pinyin1.equals(pinyin2)) {
                        return pinyin1.compareTo(pinyin2);
                    }
                } else {
                    return codePoint1 - codePoint2;
                }
            }
        }
        return o1.length() - o2.length();
    }

    /**
     * 字符的拼韻I多音字就得到W一个拼韟뀂不是汉字,return null?br>     */
    private String pinyin(char c) {
        String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
        if (pinyins == null) {
            return null;
        }
        return pinyins[0];
    }
}

试Q?/p>

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.test;

import java.util.Comparator;

import org.junit.Assert;
import org.junit.Test;

import chinese.utility.PinyinComparator;

public class PinyinComparatorTest {

    private Comparator<String> comparator = new PinyinComparator();

    /**
     * 常用?br>     */
    @Test
    public void testCommon() {
        Assert.assertTrue(comparator.compare("?, "?) < 0);
    }

    /**
     * 不同长度
     */
    @Test
    public void testDifferentLength() {
        Assert.assertTrue(comparator.compare("他奶奶的", "他奶奶的?) < 0);
    }

    /**
     * 和非汉字比较
     */
    @Test
    public void testNoneChinese() {
        Assert.assertTrue(comparator.compare("a", "?) < 0);
        Assert.assertTrue(comparator.compare("1", "?) < 0);
    }

    /**
     * 非常用字(?
     */
    @Test
    public void testNoneCommon() {
        Assert.assertTrue(comparator.compare("?, "?) < 0);
    }

    /**
     * 同音?br>     */
    @Test
    public void testSameSound() {
        Assert.assertTrue(comparator.compare("?, "?) == 0);
    }

    /**
     * 多音??
     */
    @Test
    public void testMultiSound() {
        Assert.assertTrue(comparator.compare("曄", "曾_") > 0);
    }

}

我的q样严格的拼x序还是有有待改进的地方,看上面测试代码的最后一个测试,׃发现Q程序不会根据语境来判断多音字的拼音Q仅仅是单的取多韛_的第一个拼韟?/p>

W画排序

要按W画排序Q就要实现笔L较器?/p>

class StokeComparator implements Comparator<String>

如果有个Ҏ(gu)可以求得汉字的笔LQ上面的功能很Ҏ(gu)实现。如何求一个汉字的W画敎ͼ最Ҏ(gu)惛_的就是查表法。徏一个汉字笔L表,如:

汉字 Unicode~码 W画?/td>
U4E00 1
?/td> U4E8C 2
?/td> U9F8D 16
... ... ...
表二

如果是连l的、按unicode~码排好序的表Q实际存储在W画数表中的只需最后一列就够了?/p>

那如何徏q个表呢Q这个表存储在哪里?

建汉字笔L?/h2>

现在大多数系l还只能支持Unicode中的基本汉字那部分汉字,~码从U9FA6-U9FBF。所以我们只部分汉字的笔画表。汉字笔L表,我们可以按照下面的方法生成:

  1. 用javaE序生成一个文本文?Chinese.csv)。包括所有的从U9FA6-U9FBF的字W的~码和文字。利用excel的按W画排序功能Q对Chinese.csv文g中的内容排序?
  2. ~写JavaE序分析Chinese.csv文gQ求得笔L, 生成ChineseStroke.csv。矫正笔LQ重新按汉字的Unicode~码对ChineseStroke.csv文g排序?
  3. 只保留ChineseStroke.csv文g的最后一列,生成Stroke.csv?

在这?a href="http://www.aygfsteel.com/Files/jeff-lau/Stroke.zip" target="_blank">下蝲上面3个步骤生成的3个文?/a>?/p>

生成Chinese.csv的JavaE序

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.preface;

import java.io.IOException;
import java.io.PrintWriter;

public class ChineseCoder {

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter("Chinese.csv");
        // 基本汉字
        for(char c = 0x4E00; c <= 0x9FA5; c++) {
            out.println((int)c + "," + c);
        }
        out.flush();
        out.close();

    }

}

初始化笔L

从Excel排序q后的Chinese.csv文g来看Q排好序的文件还是有一定规律的。在文g的第9?12行可以看出:逐行扫描的时候,当unicode会变了Q笔L也就??/p>

20059,?br>20101,?br>19969,?br>19970,?/p>

用下面的JavaE序分析吧?/p>

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.preface;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class Stroke {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        Scanner in = new Scanner(new File("Chinese.csv"));       
        PrintWriter out = new PrintWriter("ChineseStroke.csv");
        String oldLine = "999999";
        int stroke = 0;
        while (in.hasNextLine()) {
            String line = in.nextLine();
            if (line.compareTo(oldLine) < 0) {
                stroke++;               
            }
            oldLine = line;
            out.println(line + "," + stroke);           
        }
        out.flush();
        out.close();
        in.close();
    }

}

上面用的q个规律有问题吗Q有问题Q从ChineseStroke.csv文g抽取最后几个汉字就发现Q笔L不对。ؓ什么呢Q?/p>

  • W画数可能不是连l的?
  • n+1W画数的最Unicode码可能比nW画数的最大Unicode码要?

我们要h工核对ChineseStroke文gQ但只要核对在笔d化的那几个汉字的W画数。最后,我发玎ͼ只有W画数多?0的少数几个汉字的W画C寏V核对ƈ矫正W画数后Q用Excel按Unicode重新排序Q去掉汉字和Unicode两列Q只保留W画数那列,得到Stroke.csv文g?/p>

求得W画数的Ҏ(gu)和笔L较器Ҏ(gu)

求得W画数的Ҏ(gu)试代码Q?

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.test;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;
import chinese.utility.Chinese;

public class StrokeTest {

    Chinese chinese;

    @Before
    public void setUp() {
        chinese = new Chinese();
    }

    @Test
    public void testStroke() {
        assertEquals(1, chinese.stroke('一'));
    }

    @Test
    public void testStroke2() {
        assertEquals(2, chinese.stroke('?));
    }

    @Test
    public void testStroke16() {
        assertEquals(16, chinese.stroke('?));
    }

    @Test
    public void testStrokeABC() {
        assertEquals(-1, chinese.stroke('a'));
    }

}

求得W画数的Ҏ(gu)代码

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility;

import java.util.Comparator;

public class StrokeComparator implements Comparator<String> {

    public int compare(String o1, String o2) {

        Chinese chinese = new Chinese();

        for (int i = 0; i < o1.length() && i < o2.length(); i++) {
            int codePoint1 = o1.codePointAt(i);
            int codePoint2 = o2.codePointAt(i);
            if (codePoint1 == codePoint2)
                continue;

            int stroke1 = chinese.stroke(codePoint1);
            int stroke2 = chinese.stroke(codePoint2);

            if (stroke1 < 0 || stroke2 < 0) {
                return codePoint1 - codePoint2;
            }

            if (stroke1 != stroke2) {
                return stroke1 - stroke2;
            }
        }

        return o1.length() - o2.length();
    }
}

W画比较器测?/h3>

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.test;

import java.util.Comparator;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import chinese.utility.StrokeComparator;

public class StrokeComparatorTest {

    private Comparator<String> comparator;
    @Before
    public void setUp() {
        comparator = new StrokeComparator();
    }

    /**
     * 相同W画?br>     */
    @Test
    public void testCompareEquals() {
        Assert.assertTrue(comparator.compare("一", "?) == 0);
    }
    /**
     * 不同W画?br>     */
    @Test
    public void testCompare() {
        Assert.assertTrue(comparator.compare("一", "?) < 0);
        Assert.assertTrue(comparator.compare("?, "?) > 0);
    }
    /**
     * 长度不同
     */
    @Test
    public void testCompareDefficultLength() {
        Assert.assertTrue(comparator.compare("?, "二一") < 0);
    }
    /**
     * 非汉字的比较
     */
    @Test
    public void testABC() {
        Assert.assertTrue(comparator.compare("一", "a") > 0);
        Assert.assertTrue(comparator.compare("a", "b") < 0);       
    }
}

W画比较?

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility.test;

import java.util.Comparator;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import chinese.utility.StrokeComparator;

public class StrokeComparatorTest {

    private Comparator<String> comparator;
    @Before
    public void setUp() {
        comparator = new StrokeComparator();
    }

    /**
     * 相同W画?br>     */
    @Test
    public void testCompareEquals() {
        Assert.assertTrue(comparator.compare("一", "?) == 0);
    }
    /**
     * 不同W画?br>     */
    @Test
    public void testCompare() {
        Assert.assertTrue(comparator.compare("一", "?) < 0);
        Assert.assertTrue(comparator.compare("?, "?) > 0);
    }
    /**
     * 长度不同
     */
    @Test
    public void testCompareDefficultLength() {
        Assert.assertTrue(comparator.compare("?, "二一") < 0);
    }
    /**
     * 非汉字的比较
     */
    @Test
    public void testABC() {
        Assert.assertTrue(comparator.compare("一", "a") > 0);
        Assert.assertTrue(comparator.compare("a", "b") < 0);       
    }
}

其他E序的汉字排?/h1>

Microsoft在这斚w做得比较好。如Sql server 2000QW(xu)ord和Excel都能按拼韛_W画排序。而Oracle只能是采取宽松拼x序法?



Jeff Lau 2007-12-21 11:29 发表评论
]]>中文排序 Q?W画http://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.htmlJeff LauJeff LauThu, 20 Dec 2007 12:39:00 GMThttp://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.htmlhttp://www.aygfsteel.com/jeff-lau/comments/169147.htmlhttp://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.html#Feedback0http://www.aygfsteel.com/jeff-lau/comments/commentRss/169147.htmlhttp://www.aygfsteel.com/jeff-lau/services/trackbacks/169147.html摘要Q在很多中文书籍的作者页中,有很多作者的话,很多时候,是按作者姓名的W画序排序的。Microsoft的Excel和Sql Server实现了按W画排序的功能。那按笔画顺序排序,在Java中究竟怎样实现呢?


作者:Jeff 发表于:2007-12-20 20:39 最后更CQ?2007q?2?1?12:17
版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本版权声?/a>?br>http://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.html


合ƈ?/h1>

已经?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.html">中文排序--W画》和?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.html">中文排序--汉语拼音》修改ƈ合ƈ?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html">中文排序》中。这里只保留最后的代码。实现的原理和方法请?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html">中文排序

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility;

import java.util.Comparator;

public class StrokeComparator implements Comparator<String> {

    public int compare(String o1, String o2) {

        Chinese chinese = new Chinese();

        for (int i = 0; i < o1.length() && i < o2.length(); i++) {
            int codePoint1 = o1.codePointAt(i);
            int codePoint2 = o2.codePointAt(i);
            if (codePoint1 == codePoint2)
                continue;

            int stroke1 = chinese.stroke(codePoint1);
            int stroke2 = chinese.stroke(codePoint2);

            if (stroke1 < 0 || stroke2 < 0) {
                return codePoint1 - codePoint2;
            }

            if (stroke1 != stroke2) {
                return stroke1 - stroke2;
            }
        }

        return o1.length() - o2.length();
    }
}



Jeff Lau 2007-12-20 20:39 发表评论
]]>中文排序 Q?汉语拼音http://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.htmlJeff LauJeff LauWed, 19 Dec 2007 00:30:00 GMThttp://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.htmlhttp://www.aygfsteel.com/jeff-lau/comments/168637.htmlhttp://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.html#Feedback2http://www.aygfsteel.com/jeff-lau/comments/commentRss/168637.htmlhttp://www.aygfsteel.com/jeff-lau/services/trackbacks/168637.html摘要Q中文一般都是按拼音来排序的。但Java中的StringcL按Unicode~码存储数据的,因此QStringcM是按Unicode~码的大来排序的。Sun公司提供一个CollatorcL重新按不同的规则对字W串排序Q但Collator对中文的排序方式只是不严格的拼音排序法。Microsoft的Excel和Sql Server实现了按拼音排序的功能,比Collator实现的好多了。那如何在Java中实现类似Microsoft的拼x序的方式呢?


作者:Jeff 发表于:2007-12-19 08:30 最后更CQ?2007q?2?1?12:33
版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本版权声?/a>?br>http://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.html


合ƈ?/h1>

已经?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/20/169147.html">中文排序--W画》和?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168637.html">中文排序--汉语拼音》修改ƈ合ƈ?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html">中文排序》中。这里只保留最后的代码。实现的原理和方法请?a href="http://www.aygfsteel.com/jeff-lau/archive/2007/12/21/169257.html">中文排序?/p>

/**
  * @author Jeff
  *
  * Copyright (c) 复制或{载本文,请保留该注释?br>  */
package chinese.utility;

import java.util.Comparator;
import net.sourceforge.pinyin4j.PinyinHelper;

public class PinyinComparator implements Comparator<String> {

    public int compare(String o1, String o2) {

        for (int i = 0; i < o1.length() && i < o2.length(); i++) {

            int codePoint1 = o1.charAt(i);
            int codePoint2 = o2.charAt(i);

            if (Character.isSupplementaryCodePoint(codePoint1)
                    || Character.isSupplementaryCodePoint(codePoint2)) {
                i++;
            }

            if (codePoint1 != codePoint2) {
                if (Character.isSupplementaryCodePoint(codePoint1)
                        || Character.isSupplementaryCodePoint(codePoint2)) {
                    return codePoint1 - codePoint2;
                }

                String pinyin1 = pinyin((char) codePoint1);
                String pinyin2 = pinyin((char) codePoint2);

                if (pinyin1 != null && pinyin2 != null) { // 两个字符都是汉字
                    if (!pinyin1.equals(pinyin2)) {
                        return pinyin1.compareTo(pinyin2);
                    }
                } else {
                    return codePoint1 - codePoint2;
                }
            }
        }
        return o1.length() - o2.length();
    }

    /**
     * 字符的拼韻I多音字就得到W一个拼韟뀂不是汉字,return null?br>     */
    private String pinyin(char c) {
        String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
        if (pinyins == null) {
            return null;
        }
        return pinyins[0];
    }
}



Jeff Lau 2007-12-19 08:30 发表评论
]]>跟老刘学Java (一)http://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168636.htmlJeff LauJeff LauTue, 18 Dec 2007 20:48:00 GMThttp://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168636.htmlhttp://www.aygfsteel.com/jeff-lau/comments/168636.htmlhttp://www.aygfsteel.com/jeff-lau/archive/2007/12/19/168636.html#Feedback7http://www.aygfsteel.com/jeff-lau/comments/commentRss/168636.htmlhttp://www.aygfsteel.com/jeff-lau/services/trackbacks/168636.html老刘是个Java高手了,刘是个Java菜鸟Q最q小刘跟着老刘开始学Java。你问我Q小刘和老刘什么关p?也许他们是兄妹吧。小刘是个MM啊,Ҏ(gu)亮吗QQQh多少QMSN呢……闲话少_a归正传?/p>

(刘走向正在玩电(sh)脑的老刘w边)

刘Q老刘Q?刘一直都是这么称D刘?。教我学Java吧!

老刘Q好Q?对于刘的要求,老刘从没拒绝q?

刘Q可我对Java什么都不会Q?/p>

老刘Q有我在Q一切都没问题!(在小刘面前,老刘dƢ吹嘘?我们先装个Java开发运行环境吧?/p>

刘Q好呢!

老刘Q我们先到Sun公司的网站下载一个JDK。JDK是用来开发Java的工兗?/p>

刘QSunQ就是天上的那个太阳啊!原来Java是太阛_司的啊!

老刘Q基本上可以q么说。其他公怹有JDK产品。比如:IBM?/p>

刘QIBM我知道。被我国的联惛_司收购了嘛!

老刘Q?轻轻W了一?Q就是那个IBM。不q联惛_收购了IBM的一个部门而已?/p>

 

(刘在老刘的指gQ从SUN|站下蝲一个最新的JDKQ现在正在下载中…?

刘Q刚才在SUN|站Q我看到有个Java SE, Java EE,q有个…?/p>

老刘Q还有Java ME。这是JavaZ同的q行环境准备?U不同版本,他们用的都是Java语言Q学好Java语言p开?U不同应用程序了(Java在这3U版本除了用的Java的语法相同外Q还有很多很多不同的东西要掌握,才能不同完成开发工作,Z不打d刘学?fn)的U极性,把SUN蒙h的那套也用上?。Java SE是Java的标准版QJava ME是用于手Y件开发的QJava EE是用于企业应用开发,比如|站啊?/p>

刘QJavaq能建网站。我学会JavaQ就能用JavaZ个自己漂亮的个h|站了?托着下巴QԒ着头开始遐想了…?

老刘Q??******Q\途遥q着?那就先学好Java吧?/p>

(刘回到现实Q老刘l箋解释)

老刘QJava SE可以说其他版本的基础。我们就学Java SE。现在最新的Java SE?.0Q下载页面在http://java.sun.com/javase/downloads/index.jsp?/p>

 

(?sh)脑提示Q下载成功了)

老刘Q现在安装吧?strong>注意QJava的默认目录是C:\Program Files\..., 最好不要把Java带有I格的\径中?/strong>我们安装在D:\java目录中吧。Java SE安装包中Q除了JDKQ还有JRE。装好JDK后,会提CZ是否安装JREQ我们一起安装了吧?/p>

刘Q什么是JREQ?/p>

老刘QJRE是Javaq行环境。如果你只想q行JavaE序Q就不用安装JDKQ只需要安装一个JRE够了。现在安装好了。我们来写第一个全世界最有名的程序:HelloWorld?/p>

(老刘用记事本创徏下面一个文ӞHelloWorld.java)

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }

}

 

(老刘打开命oH口Q输入:javac HelloWorld.java。电(sh)脑显C:'javac' 不是内部或外部命令,也不是可q行的程序或批处理文件?

老刘Q我们的?sh)脑是WinXPpȝQ和W(xu)in2000一P都是WinNTpȝ的。设|一下环境变量,p正常~译了?/p>

老刘通过点击 我的?sh)?--> 属?--> 高 --> 环境变量 打开了环境变量设|对话框。在pȝ变量中加?/p>

JAVA_HOME=D:\java   (新徏?

path=%JAVA_HOME%\bin; (q加在path变量最前面)

 

(老刘再次打开命oH口Q输入:javac HelloWorld.java。正怺。输入:java HelloWorld。电(sh)脑显CHello World!)

老刘Q先休息一下。等会儿你自q我刚才那P写一个HelloWorld.java文gQƈ~译和运行它?/p>

刘Q好的?/p>

(刘是个好学的菜鸟,不休息就开始她的第一个JavaE序了…?

 

(HelloWorld.java虽然单短,_心的小刘也输错了。在~译的时候出来了一堆错误,在老刘的帮助下Q一一Ҏ(gu)了这些错误。运行成功的时候,刘高兴的蟩了v来。觉得自己已l是Java高手了。高兴过后,刘满心疑问…?

刘Q老刘Q这些代码中的单词都什么意思?

老刘Q这么,明天再讲吧!



Jeff Lau 2007-12-19 04:48 发表评论
]]>
վ֩ģ壺 Ϫ| ˮ| ɽ| ³| | | | ̨| | ѷ| ƽ| | ϴ| | | ƫ| | ƽ| | ̽| | | ˮ| | | Խ| | | | | ¡| | | | ±| | ó| | | | |