<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-16  評(píng)論-50  文章-2  trackbacks-0

    摘要:在Java中,對(duì)一個(gè)數(shù)組或列表(在本文中統(tǒng)稱為集合)中的元素排序,是一個(gè)很經(jīng)常的事情。好在Sun公司在Java庫(kù)中實(shí)現(xiàn)了大部分功能。如果集合中的元素實(shí)現(xiàn)了Comparable接口,調(diào)用Array或Collections的靜態(tài)(static)方法sort,就可以直接對(duì)集合排序。程序員用不同的方式實(shí)現(xiàn)了Comparator接口,就可以用各自不同的方式排序。對(duì)于包含漢字的字符串來(lái)說(shuō),排序的方式主要有兩種:一種是拼音,一種是筆畫(huà)。本文就講述如何實(shí)現(xiàn)這兩種不同的比較器(Comparator)。


    作者:Jeff 發(fā)表于:2007年12月21日 11:27 最后更新于: 2007年12月21日 12:38
    版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本版權(quán)聲明。
    http://m.tkk7.com/jeff-lau/archive/2007/12/21/169257.html


    排序概述

    在Java中,對(duì)一個(gè)數(shù)組或列表(在本文中統(tǒng)稱為集合)中的元素排序,是一個(gè)很經(jīng)常的事情。好在Sun公司在Java庫(kù)中實(shí)現(xiàn)了大部分功能。如果集合中的元素實(shí)現(xiàn)了Comparable接口,調(diào)用以下的靜態(tài)(static)方法,就可以直接對(duì)集合排序。

    // 數(shù)組排序方法
    // 數(shù)組中的元素可以是像int這樣的原生類型(primitive type), 也可以是像String這樣實(shí)現(xiàn)了Comparable接口的類型,這里用type表示。
    java.util.Arrays.sort(type[] a);

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

    以上的這些排序方式能滿足大部分應(yīng)用。但集合中的元素沒(méi)有實(shí)現(xiàn)Comparable接口,或者集合中的元素要按一種特別的方式排序,這要怎么辦?Sun公司早就想到了,并在Java庫(kù)中提供上面兩個(gè)方法的重載。

    // 數(shù)組排序方法。
    // 數(shù)組中的元素可以是像int這樣的原生類型(primitive type), 也可以是像String這樣實(shí)現(xiàn)了Comparable接口的類型,這里用type表示。
    public static <T> void sort(T[] a, Comparator<? super T> c)

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

    只要實(shí)現(xiàn)了Comparator接口,就可以按程序員自己的意思去排序了。對(duì)于包含漢字的字符串來(lái)說(shuō),排序的方式主要有兩種:一種是拼音,一種是筆畫(huà)。漢字是通過(guò)一定的編碼方式存儲(chǔ)在計(jì)算機(jī)上的,主要的編碼有:Unicdoe、GB2312和GBK等。

    Unicode 編碼中的漢字

    Unicode中編碼表分為兩塊,一個(gè)是基本的,一個(gè)是輔助的?,F(xiàn)在的大多數(shù)操作系統(tǒng)還不支持Unicode中輔助區(qū)域中的文字,如WinXp。

    在Java中的字符就是Unicode碼表示的。對(duì)于Unicode基本區(qū)域中的文字,用兩個(gè)字節(jié)的內(nèi)存存儲(chǔ),用一個(gè)char表示,而輔助區(qū)域中的文字用4個(gè)字節(jié)存儲(chǔ),因此輔助區(qū)域中的就要用兩個(gè)char來(lái)表示了(表一種藍(lán)色底就是輔助區(qū)域中的文字)。一個(gè)文字的unicode編碼,在Java中統(tǒng)一用codePoint(代碼點(diǎn))這個(gè)概念。

    中文和日文、韓文一樣是表意文字,在Unicode中,中日韓三國(guó)(東亞地區(qū))的文字是統(tǒng)一編碼的。CJK代表的就是中日韓。在這里,我把這3中文字,都作為漢字處理了。(日語(yǔ)和韓語(yǔ)可能就是從漢語(yǔ)中衍生的吧!)

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

      首字編碼 尾字編碼 個(gè)數(shù)
    基本漢字 U4E00 U9FBF 20928
    異性字 UF900 UFAFF 512
    擴(kuò)展A U3400 U4D8F 512
    擴(kuò)展B U20000 U2A6DF 42720
    補(bǔ)充 U2F800 U2FA1F 544
    其他     ...
    表一

    在這些編碼區(qū)間,有些編碼是保留的。

    GB2312編碼

    GB2312是中華人民共和國(guó)最早的計(jì)算機(jī)漢字編碼方式。大概有6000多個(gè)漢字,這些漢字是按拼音順序編碼的。這6000多個(gè)漢字都是簡(jiǎn)體中文字。

    GBK編碼

    GB2312的擴(kuò)展,并兼容GB2312。擴(kuò)展后的漢字大概有2萬(wàn)多個(gè),其中有簡(jiǎn)體漢字也有繁體漢字。

    拼音排序

    拼音有好幾種方式,其中最主要的是中華人民共和國(guó)的漢語(yǔ)拼音 Chinese Phonetic。對(duì)漢字的排序有兩種:一種是寬松的,能夠按拼音排序最常用的漢字,另一種是嚴(yán)格的,能夠按拼音排序絕大部分大部分漢字。

    寬松的拼音排序法

    原理:漢字最早是GB2312編碼,收錄了六千多個(gè)漢字,是按拼音排序的,編碼是連續(xù)的。 后來(lái)出現(xiàn)了GBK編碼,對(duì)GB2312進(jìn)行了擴(kuò)展,到了兩萬(wàn)多漢字,并且兼容GB2312,也就是說(shuō)GB2312中的漢字編碼是原封不動(dòng)搬到GBK中的(在GBK編碼中[B0-D7]區(qū)中)。

    如果我們只關(guān)心這6000多個(gè)漢字的順序,就可以用下面的方法實(shí)現(xiàn)漢字寬松排序。

    /**
    * @author Jeff
    *
    * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
    */

    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);
        }
    }

    在對(duì)[孫, 孟, 宋, 尹, 廖, 張, 徐, 昆, 曹, 曾,怡]這幾個(gè)漢字排序,結(jié)果是:[曹, 昆, 廖, 孟, 宋, 孫, 徐, 尹, 曾, 張, 怡]。最后一個(gè) 有問(wèn)題,不該排在最后的。

    注意:這個(gè)程序有兩個(gè)不足

    • 由于gb2312中的漢字編碼是連續(xù)的,因此新增加的漢字不可能再按照拼音順序插入到已有的gb2312編碼中,所以新增加的漢字不是按拼音順序排的。
    • 同音字比較的結(jié)果不等于0 。

    下面的測(cè)試代碼可以證明

    /**
    * @author Jeff
    *
    * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
    */

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

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

    嚴(yán)格的拼音排序法

    為了解決寬松的拼音的兩點(diǎn)不足,可以通過(guò)實(shí)現(xiàn)漢語(yǔ)拼音的函數(shù)來(lái)解決。goolge下看到sf上有個(gè)pinyin4j的項(xiàng)目,可以解決這個(gè)問(wèn)題,pinyin4j的項(xiàng)目地址是:http://pinyin4j.sourceforge.net/。

    實(shí)現(xiàn)代碼:

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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) { // 兩個(gè)字符都是漢字
                        if (!pinyin1.equals(pinyin2)) {
                            return pinyin1.compareTo(pinyin2);
                        }
                    } else {
                        return codePoint1 - codePoint2;
                    }
                }
            }
            return o1.length() - o2.length();
        }

        /**
         * 字符的拼音,多音字就得到第一個(gè)拼音。不是漢字,就return null。
         */
        private String pinyin(char c) {
            String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
            if (pinyins == null) {
                return null;
            }
            return pinyins[0];
        }
    }

    測(cè)試:

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();

        /**
         * 常用字
         */
        @Test
        public void testCommon() {
            Assert.assertTrue(comparator.compare("孟", "宋") < 0);
        }

        /**
         * 不同長(zhǎng)度
         */
        @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);
        }

        /**
         * 同音字
         */
        @Test
        public void testSameSound() {
            Assert.assertTrue(comparator.compare("怕", "帕") == 0);
        }

        /**
         * 多音字(曾)
         */
        @Test
        public void testMultiSound() {
            Assert.assertTrue(comparator.compare("曾經(jīng)", "曾迪") > 0);
        }

    }

    我的這樣嚴(yán)格的拼音排序還是有有待改進(jìn)的地方,看上面測(cè)試代碼的最后一個(gè)測(cè)試,就會(huì)發(fā)現(xiàn):程序不會(huì)根據(jù)語(yǔ)境來(lái)判斷多音字的拼音,僅僅是簡(jiǎn)單的取多音字的第一個(gè)拼音。

    筆畫(huà)排序

    要按筆畫(huà)排序,就要實(shí)現(xiàn)筆畫(huà)比較器。

    class StokeComparator implements Comparator<String>

    如果有個(gè)方法可以求得漢字的筆畫(huà)數(shù),上面的功能就很容易實(shí)現(xiàn)。如何求一個(gè)漢字的筆畫(huà)數(shù)?最容易想到的就是查表法。建一個(gè)漢字筆畫(huà)數(shù)表,如:

    漢字 Unicode編碼 筆畫(huà)數(shù)
    U4E00 1
    U4E8C 2
    U9F8D 16
    ... ... ...
    表二

    如果是連續(xù)的、按unicode編碼排好順序的表,實(shí)際存儲(chǔ)在筆畫(huà)數(shù)表中的只需最后一列就夠了。

    那如何建這個(gè)表呢?這個(gè)表存儲(chǔ)在哪里?

    建漢字筆畫(huà)數(shù)表

    現(xiàn)在大多數(shù)系統(tǒng)還只能支持Unicode中的基本漢字那部分漢字,編碼從U9FA6-U9FBF。所以我們只建這部分漢字的筆畫(huà)表。漢字筆畫(huà)數(shù)表,我們可以按照下面的方法生成:

    1. 用java程序生成一個(gè)文本文件(Chinese.csv)。包括所有的從U9FA6-U9FBF的字符的編碼和文字。利用excel的按筆畫(huà)排序功能,對(duì)Chinese.csv文件中的內(nèi)容排序。
    2. 編寫(xiě)Java程序分析Chinese.csv文件,求得筆畫(huà)數(shù), 生成ChineseStroke.csv。矯正筆畫(huà)數(shù),重新按漢字的Unicode編碼對(duì)ChineseStroke.csv文件排序。
    3. 只保留ChineseStroke.csv文件的最后一列,生成Stroke.csv。

    在這里下載上面3個(gè)步驟生成的3個(gè)文件。

    生成Chinese.csv的Java程序

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();

        }

    }

    初始化筆畫(huà)數(shù)

    從Excel排序過(guò)后的Chinese.csv文件來(lái)看,排好序的文件還是有一定規(guī)律的。在文件的第9行-12行可以看出:逐行掃描的時(shí)候,當(dāng)unicode會(huì)變小了,筆畫(huà)數(shù)也就加1。

    20059,乛
    20101,亅
    19969,丁
    19970,丂

    用下面的Java程序分析吧。

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();
        }

    }

    上面用的這個(gè)規(guī)律有問(wèn)題嗎?有問(wèn)題,從ChineseStroke.csv文件抽取最后幾個(gè)漢字就發(fā)現(xiàn),筆畫(huà)數(shù)不對(duì)。為什么呢?

    • 筆畫(huà)數(shù)可能不是連續(xù)的。
    • n+1筆畫(huà)數(shù)的最小Unicode碼可能比n筆畫(huà)數(shù)的最大Unicode碼要大

    我們要人工核對(duì)ChineseStroke文件,但只要核對(duì)在筆畫(huà)變化的那幾個(gè)漢字的筆畫(huà)數(shù)。最后,我發(fā)現(xiàn),只有筆畫(huà)數(shù)多于30的少數(shù)幾個(gè)漢字的筆畫(huà)數(shù)不對(duì)。核對(duì)并矯正筆畫(huà)數(shù)后,用Excel按Unicode重新排序,去掉漢字和Unicode兩列,只保留筆畫(huà)數(shù)那列,得到Stroke.csv文件。

    求得筆畫(huà)數(shù)的方法和筆畫(huà)比較器方法

    求得筆畫(huà)數(shù)的方法測(cè)試代碼:

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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'));
        }

    }

    求得筆畫(huà)數(shù)的方法代碼

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();
        }
    }

    筆畫(huà)比較器測(cè)試

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();
        }

        /**
         * 相同筆畫(huà)數(shù)
         */
        @Test
        public void testCompareEquals() {
            Assert.assertTrue(comparator.compare("一", "丨") == 0);
        }
        /**
         * 不同筆畫(huà)數(shù)
         */
        @Test
        public void testCompare() {
            Assert.assertTrue(comparator.compare("一", "二") < 0);
            Assert.assertTrue(comparator.compare("唔", "馬") > 0);
        }
        /**
         * 長(zhǎng)度不同
         */
        @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);       
        }
    }

    筆畫(huà)比較器

    /**
      * @author Jeff
      *
      * Copyright (c) 復(fù)制或轉(zhuǎn)載本文,請(qǐng)保留該注釋。
      */
    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();
        }

        /**
         * 相同筆畫(huà)數(shù)
         */
        @Test
        public void testCompareEquals() {
            Assert.assertTrue(comparator.compare("一", "丨") == 0);
        }
        /**
         * 不同筆畫(huà)數(shù)
         */
        @Test
        public void testCompare() {
            Assert.assertTrue(comparator.compare("一", "二") < 0);
            Assert.assertTrue(comparator.compare("唔", "馬") > 0);
        }
        /**
         * 長(zhǎng)度不同
         */
        @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);       
        }
    }

    其他程序的漢字排序

    Microsoft在這方面做得比較好。如Sql server 2000,Word和Excel都能按拼音和筆畫(huà)排序。而Oracle只能是采取寬松拼音排序法。

    posted on 2007-12-21 11:29 Jeff Lau 閱讀(11903) 評(píng)論(10)  編輯  收藏 所屬分類: 跟老劉學(xué)Java

    評(píng)論:
    # re: 中文排序 2007-12-21 12:42 | sitinspring
    好文章!  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2007-12-23 10:47 | ci
    好.........  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2008-01-03 18:52 | hill911
    好文章
    值得研究  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2008-08-12 17:35 | vv0885
    長(zhǎng)知識(shí),謝謝前輩!

    但是我沒(méi)有找到Chinese這個(gè)類!  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2008-12-02 11:48 | Arix
    筆畫(huà)排序的資料幫了很大的忙,感謝。  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2011-01-10 09:52 | 唐永軍
    謝謝。學(xué)習(xí)了。
      回復(fù)  更多評(píng)論
      
    # re: 中文排序 2011-08-01 22:59 | 徐冬冬
    很不錯(cuò) 值得 一看   回復(fù)  更多評(píng)論
      
    # re: 中文排序[未登錄](méi) 2011-10-19 12:59 | xx
    @vv0885
    人家這個(gè)類是在下載那個(gè)sourceforge中的jar包的哦。  回復(fù)  更多評(píng)論
      
    # re: 中文排序[未登錄](méi) 2011-11-07 17:36 | andy
    效率很低啊,怎么辦呢  回復(fù)  更多評(píng)論
      
    # re: 中文排序 2013-02-21 16:57 | zhenshao
    chinese 類貌似找不到呢,在線等.....  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 男女啪啪免费体验区| 亚洲18在线天美| 亚欧乱色国产精品免费视频| 日本免费一本天堂在线| 亚洲欧洲专线一区| 日韩免费视频一区| 久久亚洲中文无码咪咪爱| 哒哒哒免费视频观看在线www| 国产精品观看在线亚洲人成网| 好男人视频在线观看免费看片| 亚洲成人黄色网址| 欧美好看的免费电影在线观看| 亚洲精品美女网站| 日本高清免费aaaaa大片视频| 久久精品国产亚洲av品善| 免费大香伊蕉在人线国产| 五月天婷婷精品免费视频| 亚洲综合AV在线在线播放| 免费精品99久久国产综合精品| 亚洲午夜久久影院| 99在线视频免费观看视频| 亚洲AV综合色区无码一二三区 | 亚洲午夜久久久影院伊人| 青青操免费在线观看| 久久精品国产亚洲AV无码麻豆 | 亚洲免费视频网站| 亚洲fuli在线观看| 在线观看免费人成视频色9| 亚洲国产区男人本色| 亚洲AV永久无码精品一区二区国产| 国产成人无码免费看片软件| 亚洲AV永久纯肉无码精品动漫| 精品女同一区二区三区免费站| 亚洲av永久无码天堂网| 国产中文在线亚洲精品官网| 99久在线国内在线播放免费观看| 亚洲色大网站WWW永久网站| 国产成人精品亚洲精品| **aaaaa毛片免费| 曰批全过程免费视频免费看| 亚洲欧洲日产国产综合网|