青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

為生存而奔跑

   :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

留言簿(5)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 331734
  • 排名 - 74

最新評論

閱讀排行榜

評論排行榜

 

 

KMP字符串模式匹配通俗點說就是一種在一個字符串中定位另一個串的高效算法。簡單匹配算法的時間復雜度為O(m*n);KMP匹配算法。可以證明它的時間復雜度為O(m+n).

. 簡單匹配算法

先來看一個簡單匹配算法的函數(shù):

int Index_BF ( char S [ ], char T [ ], int pos )

{

/* 若串 S 中從第pos(S 的下標0≤pos<StrLength(S))個字符

起存在和串 T 相同的子串,則稱匹配成功,返回第一個

這樣的子串在串 S 中的下標,否則返回 -1    */

int i = pos, j = 0;

while ( S[i+j] != '\0'&& T[j] != '\0')

if ( S[i+j] == T[j] )

j ++; // 繼續(xù)比較后一字符

else

{

i ++; j = 0; // 重新開始新的一輪匹配

}

if ( T[j] == '\0')

return i; // 匹配成功   返回下標

else

return -1; // S(pos個字符起)不存在和串T相同的子串

} // Index_BF
   
此算法的思想是直截了當?shù)模簩⒅鞔?/span>S中某個位置i起始的子串和模式串T相比較。即從 j=0 起比較 S[i+j] T[j],若相等,則在主串 S 中存在以 i 為起始位置匹配成功的可能性,繼續(xù)往后比較( j逐步增1 ),直至與T串中最后一個字符相等為止,否則改從S串的下一個字符起重新開始進行下一輪的"匹配",即將串T向后滑動一位,即 i 1,而 j 退回至0,重新開始新一輪的匹配。

例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我們可以假設從下標0開始):先是比較S[0]T[0]是否相等,然后比較S[1] T[1]是否相等我們發(fā)現(xiàn)一直比較到S[5] T[5]才不等。如圖:

 

當這樣一個失配發(fā)生時,T下標必須回溯到開始,S下標回溯的長度與T相同,然后S下標增1,然后再次比較。如圖:

這次立刻發(fā)生了失配,T下標又回溯到開始,S下標增1,然后再次比較。如圖:

這次立刻發(fā)生了失配,T下標又回溯到開始,S下標增1,然后再次比較。如圖:

又一次發(fā)生了失配,所以T下標又回溯到開始,S下標增1,然后再次比較。這次T中的所有字符都和S中相應的字符匹配了。函數(shù)返回TS中的起始下標3。如圖:

. KMP 匹配算法

還是相同的例子,在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,當?shù)谝淮嗡阉鞯?/span>S[5] T[5]不等后,S下標不是回溯到1T下標也不是回溯到開始,而是根據(jù)TT[5]==’d’的模式函數(shù)值(next[5]=2,為什么?后面講),直接比較S[5] T[2]是否相等,因為相等,ST的下標同時增加;因為又相等,ST的下標又同時增加。。。最終在S中找到了T。如圖:



KMP匹配算法和簡單匹配算法效率比較,一個極端的例子是:

S=“AAAAAA…AAB“(100A)中查找T=”AAAAAAAAAB”, 簡單匹配算法每次都是比較到T的結尾,發(fā)現(xiàn)字符不同,然后T的下標回溯到開始,S的下標也要回溯相同長度后增1,繼續(xù)比較。如果使用KMP匹配算法,就不必回溯.

對于一般文稿中串的匹配,簡單匹配算法的時間復雜度可降為O (m+n),因此在多數(shù)的實際應用場合下被應用。

KMP算法的核心思想是利用已經(jīng)得到的部分匹配信息來進行后面的匹配過程。看前面的例子。為什么T[5]==’d’的模式函數(shù)值等于2next[5]=2),其實這個2表示T[5]==’d’的前面有2個字符和開始的兩個字符相同,且T[5]==’d’不等于開始的兩個字符之后的第三個字符(T[2]=’c’.如圖:

也就是說,如果開始的兩個字符之后的第三個字符也為’d’,那么,盡管T[5]==’d’的前面有2個字符和開始的兩個字符相同,T[5]==’d’的模式函數(shù)值也不為2,而是為0

   前面我說:在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,當?shù)谝淮嗡阉鞯?/span>S[5] T[5]不等后,S下標不是回溯到1T下標也不是回溯到開始,而是根據(jù)TT[5]==’d’的模式函數(shù)值,直接比較S[5] T[2]是否相等。。。為什么可以這樣?

剛才我又說:next[5]=2),其實這個2表示T[5]==’d’的前面有2個字符和開始的兩個字符相同。請看圖 :因為,S[4] ==T[4]S[3] ==T[3],根據(jù)next[5]=2,有T[3]==T[0]T[4] ==T[1],所以S[3]==T[0]S[4] ==T[1](兩對相當于間接比較過了),因此,接下來比較S[5] T[2]是否相等。。。

有人可能會問:S[3]T[0]S[4] T[1]是根據(jù)next[5]=2間接比較相等,那S[1]T[0]S[2] T[0]之間又是怎么跳過,可以不比較呢?因為S[0]=T[0]S[1]=T[1]S[2]=T[2],而T[0] != T[1], T[1] != T[2],==> S[0] != S[1],S[1] != S[2],所以S[1] != T[0],S[2] != T[0]. 還是從理論上間接比較了。

有人疑問又來了,你分析的是不是特殊輕況啊。

假設S不變,在S中搜索T=“abaabd”呢?答:這種情況,當比較到S[2]T[2]時,發(fā)現(xiàn)不等,就去看next[2]的值,next[2]=-1,意思是S[2]已經(jīng)和T[0] 間接比較過了,不相等,接下來去比較S[3]T[0]吧。

假設S不變,在S中搜索T=“abbabd”呢?答:這種情況當比較到S[2]T[2]時,發(fā)現(xiàn)不等,就去看next[2]的值,next[2]=0,意思是S[2]已經(jīng)和T[2]比較過了,不相等,接下來去比較S[2]T[0]吧。

假設S=”abaabcabdabba”S中搜索T=“abaabd”呢?答:這種情況當比較到S[5]T[5]時,發(fā)現(xiàn)不等,就去看next[5]的值,next[5]=2,意思是前面的比較過了,其中,S[5]的前面有兩個字符和T的開始兩個相等,接下來去比較S[5]T[2]吧。

總之,有了串的next值,一切搞定。那么,怎么求串的模式函數(shù)值next[n]呢?(本文中next值、模式函數(shù)值、模式值是一個意思。)

. 怎么求串的模式值 next[n]

定義

1next[0]= -1 意義:任何串的第一個字符的模式值規(guī)定為-1

2next[j]= -1   意義:模式串T中下標為j的字符,如果與首字符

相同,且j的前面的1—k個字符與開頭的1—k

個字符不等(或者相等但T[k]==T[j])(1≤k<j)。

如:T=”abCabCad” next[6]=-1,因T[3]=T[6]

3next[j]=k    意義:模式串T中下標為j的字符,如果j的前面k

字符與開頭的k個字符相等,且T[j] != T[k] 1≤k<j)。

                       T[0]T[1]T[2]。。。T[k-1]==

T[j-k]T[j-k+1]T[j-k+2]…T[j-1]

T[j] != T[k].1≤k<j;

(4) next[j]=0   意義:除(1)(2)(3)的其他情況。

 

舉例

01)求T=“abcac”的模式函數(shù)的值。

     next[0]= -1 根據(jù)(1

     next[1]=0   根據(jù) (4)   因(3)有1<=k<j;不能說,j=1,T[j-1]==T[0]

     next[2]=0   根據(jù) (4)   因(3)有1<=k<j;T[0]=a!=T[1]=b

     next[3]= -1 根據(jù) (2)

     next[4]=1   根據(jù) (3) T[0]=T[3] T[1]=T[4]

       

下標

0

1

2

3

4

T

a

b

c

a

c

next

-1

0

0

-1

1

T=“abcab”將是這樣:

下標

0

1

2

3

4

T

a

b

c

a

b

next

-1

0

0

-1

0

為什么T[0]==T[3],還會有next[4]=0, 因為T[1]==T[4], 根據(jù) (3)” T[j] != T[k]”被劃入(4)。

02)來個復雜點的,求T=”ababcaabc” 的模式函數(shù)的值。

next[0]= -1    根據(jù)(1

         next[1]=0    根據(jù)(4)

         next[2]=-1   根據(jù) (2)

next[3]=0   根據(jù) (3) T[0]=T[2] T[1]=T[3] 被劃入(4

next[4]=2   根據(jù) (3) T[0]T[1]=T[2]T[3] T[2] !=T[4]

next[5]=-1 根據(jù) (2) 

next[6]=1   根據(jù) (3) T[0]=T[5] T[1]!=T[6]

next[7]=0   根據(jù) (3) T[0]=T[6] T[1]=T[7] 被劃入(4

next[8]=2   根據(jù) (3) T[0]T[1]=T[6]T[7] T[2] !=T[8]

 

下標

0

1

2

3

4

5

6

7

8

T

a

b

a

b

c

a

a

b

c

next

-1

0

-1

0

2

-1

1

0

2

只要理解了next[3]=0,而不是=1next[6]=1,而不是= -1next[8]=2,而不是= 0,其他的好象都容易理解。

03)   來個特殊的,求 T=”abCabCad” 的模式函數(shù)的值。

下標

0

1

2

3

4

5

6

7

T

a

b

C

a

b

C

a

d

next

-1

0

0

-1

0

0

-1

4

         

next[5]= 0 根據(jù) (3) T[0]T[1]=T[3]T[4],T[2]==T[5]

next[6]= -1 根據(jù) (2) 雖前面有abC=abC,T[3]==T[6]

next[7]=4   根據(jù) (3) 前面有abCa=abCa, T[4]!=T[7]

T[4]==T[7],即T=” adCadCad”,那么將是這樣:next[7]=0, 而不是= 4,因為T[4]==T[7].

下標

0

1

2

3

4

5

6

7

T

a

d

C

a

d

C

a

d

next

-1

0

0

-1

0

0

-1

0

 

如果你覺得有點懂了,那么

練習:求T=”AAAAAAAAAAB” 的模式函數(shù)值,并用后面的求模式函數(shù)值函數(shù)驗證。

意義

 next 函數(shù)值究竟是什么含義,前面說過一些,這里總結。

設在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函數(shù)值next[n],

1.       next[n]= -1 表示S[m]T[0]間接比較過了,不相等,下一次比較 S[m+1] T[0]

2.       next[n]=0 表示比較過程中產(chǎn)生了不相等,下一次比較 S[m] T[0]

3.       next[n]= k >0 k<n, 表示,S[m]的前k個字符與T中的開始k個字符已經(jīng)間接比較相等了,下一次比較S[m]T[k]相等嗎?

4.       其他值,不可能。

. 求串 T 的模式值 next[n] 的函數(shù)

說了這么多,是不是覺得求串T的模式值next[n]很復雜呢?要叫我寫個函數(shù)出來,目前來說,我寧愿去登天。好在有現(xiàn)成的函數(shù),當初發(fā)明KMP算法,寫出這個函數(shù)的先輩,令我佩服得六體投地。我等后生小子,理解起來,都要反復琢磨。下面是這個函數(shù):

void get_nextval(const char *T, int next[])

{

       // 求模式串Tnext函數(shù)值并存入數(shù)組 next

       int j = 0, k = -1;

       next[0] = -1;

       while ( T[j/*+1*/] != '\0' )

       {

              if (k == -1 || T[j] == T[k])

              {

                     ++j; ++k;

                     if (T[j]!=T[k])

                            next[j] = k;

                     else

                            next[j] = next[k];

              }// if

              else

                     k = next[k];

       }// while

    ////這里是我加的顯示部分

   // for(int i=0;i<j;i++)

       //{

       //     cout<<next[i];

       //}

       //cout<<endl;

}// get_nextval 

另一種寫法,也差不多。

void getNext(const char* pattern,int next[])

{

       next[0]=   -1;

       int k=-1,j=0;

       while(pattern[j] != '\0')

       {

              if(k!= -1 && pattern[k]!= pattern[j] )

                     k=next[k];

              ++j;++k;

              if(pattern[k]== pattern[j])

                     next[j]=next[k];

              else

                     next[j]=k;

       }

       ////這里是我加的顯示部分

   // for(int i=0;i<j;i++)

       //{

       //     cout<<next[i];

       //}

       //cout<<endl;

}

下面是KMP模式匹配程序,各位可以用他驗證。記得加入上面的函數(shù)

#include <iostream.h>

#include <string.h>

int KMP(const char *Text,const char* Pattern) //const 表示函數(shù)內(nèi)部不會改變這個參數(shù)的值。

{

       if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )//

              return -1;//空指針或空串,返回-1

       int len=0;

       const char * c=Pattern;

       while(*c++!='\0')//移動指針比移動下標快。

       {    

              ++len;//字符串長度。

       }

       int *next=new int[len+1];

       get_nextval(Pattern,next);//Patternnext函數(shù)值

   

       int index=0,i=0,j=0;

       while(Text[i]!='\0' && Pattern[j]!='\0' )

       {

              if(Text[i]== Pattern[j])

              {

                     ++i;// 繼續(xù)比較后繼字符

                     ++j;

              }

              else

              {

                     index += j-next[j];

                     if(next[j]!=-1)

                            j=next[j];// 模式串向右移動

                     else

                     {

                            j=0;

                            ++i;

                     }

              }

       }//while

   

       delete []next;

       if(Pattern[j]=='\0')

              return index;// 匹配成功

       else

              return -1;      

}

int main()//abCabCad

{

       char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc";

    char*pattern="adCadCad";

       //getNext(pattern,n);

    //get_nextval(pattern,n);

      cout<<KMP(text,pattern)<<endl;

       return 0;

}

五.其他表示模式值的方法

上面那種串的模式值表示方法是最優(yōu)秀的表示方法,從串的模式值我們可以得到很多信息,以下稱為第一種表示方法。第二種表示方法,雖然也定義next[0]= -1,但后面絕不會出現(xiàn)-1,除了next[0],其他模式值next[j]=k(0≤k<j)的意義可以簡單看成是:下標為j的字符的前面最多k個字符與開始的k個字符相同,這里并不要求T[j] != T[k]。其實next[0]也可以定義為0(后面給出的求串的模式值的函數(shù)和串的模式匹配的函數(shù),是next[0]=0的),這樣,next[j]=k(0≤k<j)的意義都可以簡單看成是:下標為j的字符的前面最多k個字符與開始的k個字符相同。第三種表示方法是第一種表示方法的變形,即按第一種方法得到的模式值,每個值分別加1,就得到第三種表示方法。第三種表示方法,我是從論壇上看到的,沒看到詳細解釋,我估計是為那些這樣的編程語言準備的:數(shù)組的下標從1開始而不是0

 下面給出幾種方法的例子:

      表一。

下標

0

1

2

3

4

5

6

7

8

T

a

b

a

b

c

a

a

b

c

(1) next

-1

0

-1

0

2

-1

1

0

2

(2) next

-1

0

0

1

2

0

1

1

2

(3) next

0

1

0

1

3

0

2

1

3

第三種表示方法,在我看來,意義不是那么明了,不再討論。

           表二。

下標

0

1

2

3

4

T

a

b

c

A

c

(1)next

-1

0

0

-1

1

(2)next

-1

0

0

0

1

      表三。

下標

0

1

2

3

4

5

6

7

T

a

d

C

a

d

C

a

d

(1)next

-1

0

0

-1

0

0

-1

0

(2)next

-1

0

0

0

1

2

3

4

 

對比串的模式值第一種表示方法和第二種表示方法,看表一:

第一種表示方法next[2]= -1,表示T[2]=T[0],且T[2-1] !=T[0]

第二種表示方法next[2]= 0,表示T[2-1] !=T[0],但并不管T[0] T[2]相不相等。

第一種表示方法next[3]= 0,表示雖然T[2]=T[0],但T[1] ==T[3]

第二種表示方法next[3]= 1,表示T[2] =T[0],他并不管T[1] T[3]相不相等。

第一種表示方法next[5]= -1,表示T[5]=T[0],且T[4] !=T[0]T[3]T[4] !=T[0]T[1]T[2]T[3]T[4] !=T[0]T[1]T[2]

第二種表示方法next[5]= 0,表示T[4] !=T[0]T[3]T[4] !=T[0]T[1] T[2]T[3]T[4] !=T[0]T[1]T[2],但并不管T[0] T[5]相不相等。換句話說:就算T[5]==’x’, T[5]==’y’,T[5]==’9’,也有next[5]= 0

從這里我們可以看到:串的模式值第一種表示方法能表示更多的信息,第二種表示方法更單純,不容易搞錯。當然,用第一種表示方法寫出的模式匹配函數(shù)效率更高。比如說,在串S=“adCadCBdadCadCad 9876543”中匹配串T=“adCadCad”, 用第一種表示方法寫出的模式匹配函數(shù),當比較到S[6] != T[6] 時,取next[6]= -1(表三),它可以表示這樣許多信息: S[3]S[4]S[5]==T[3]T[4]T[5]==T[0]T[1]T[2],而S[6] != T[6]T[6]==T[3]==T[0],所以S[6] != T[0],接下來比較S[7]T[0]吧。如果用第二種表示方法寫出的模式匹配函數(shù),當比較到S[6] != T[6] 時,取next[6]= 3(表三),它只能表示:S[3]S[4]S[5]== T[3]T[4]T[5]==T[0]T[1]T[2],但不能確定T[6]T[3]相不相等,所以,接下來比較S[6]T[3];又不相等,取next[3]= 0,它表示S[3]S[4]S[5]== T[0]T[1]T[2],但不會確定T[3]T[0]相不相等,即S[6]T[0] 相不相等,所以接下來比較S[6]T[0],確定它們不相等,然后才會比較S[7]T[0]。是不是比用第一種表示方法寫出的模式匹配函數(shù)多繞了幾個彎。

為什么,在講明第一種表示方法后,還要講沒有第一種表示方法好的第二種表示方法?原因是:最開始,我看嚴蔚敏的一個講座,她給出的模式值表示方法是我這里的第二種表示方法,如圖:

她說:“next 函數(shù)值的含義是:當出現(xiàn)S[i] !=T[j]時,下一次的比較應該在S[i]T[next[j]] 之間進行。雖簡潔,但不明了,反復幾遍也沒明白為什么。而她給出的算法求出的模式值是我這里說的第一種表示方法next值,就是前面的get_nextval()函數(shù)。匹配算法也是有瑕疵的。于是我在這里發(fā)帖說她錯了:

http://community.csdn.net/Expert/topic/4413/4413398.xml?temp=.2027246

   現(xiàn)在看來,她沒有錯,不過有張冠李戴之嫌。我不知道,是否有人第一次學到這里,不參考其他資料和明白人講解的情況下,就能搞懂這個算法(我的意思是不僅是算法的大致思想,而是為什么定義和例子中next[j]=k(0≤k<j),而算法中next[j]=k(-1≤k<j))。憑良心說:光看這個講座,我就對這個教受十分敬佩,不僅講課講得好,聲音悅耳,而且這門課講得層次分明,恰到好處。在KMP這個問題上出了點小差錯,可能是編書的時候,在這本書上抄下了例子,在那本書上抄下了算法,結果不怎么對得上號。因為我沒找到原書,而據(jù)有的網(wǎng)友說,書上已不是這樣,也許吧。說起來,教授們研究的問題比這個高深不知多少倍,哪有時間推演這個小算法呢。總之,瑕不掩玉。

書歸正傳,下面給出我寫的求第二種表示方法表示的模式值的函數(shù),為了從S的任何位置開始匹配T當出現(xiàn)S[i] !=T[j]時,下一次的比較應該在S[i]T[next[j]] 之間進行。”    定義next[0]=0

 void myget_nextval(const char *T, int next[])

{

     // 求模式串Tnext函數(shù)值(第二種表示方法)并存入數(shù)組 next                

     int j = 1, k = 0;

     next[0] = 0;

       while ( T[j] != '\0' )

     {    

                   if(T[j] == T[k])

                   {

                         next[j] = k;

                         ++j; ++k;                 

                   }

                   else if(T[j] != T[0])

                   {

                  next[j] = k;

                  ++j;

                           k=0;

                   }

                   else

                   {

                          next[j] = k;

                  ++j;

                             k=1;

                   }

     }//while

    for(int i=0;i<j;i++)

     {

            cout<<next[i];

     }

     cout<<endl;

}// myget_nextval

 

下面是模式值使用第二種表示方法的匹配函數(shù)(next[0]=0

int my_KMP(char *S, char *T, int pos)

{

int i = pos, j = 0;//pos(S 的下標0≤pos<StrLength(S))

while ( S[i] != '\0' && T[j] != '\0' )

{

    if (S[i] == T[j] )

     {

         ++i;

             ++j; // 繼續(xù)比較后繼字符

     }

   else             // a b a b c a a b c

                    // 0 0 0 1 2 0 1 1 2

   {              //-1 0 -1 0 2 -1 1 0 2

      i++;

     j = next[j];     /*當出現(xiàn)S[i] !=T[j]時,

              下一次的比較應該在S[i]T[next[j]] 之間進行。要求next[0]=0

在這兩個簡單示范函數(shù)間使用全局數(shù)組next[]傳值。*/

   }

}//while

if ( T[j] == '\0' )

    return (i-j); // 匹配成功

else

     return -1;

} // my_KMP

六.后話 --KMP 的歷史

[這段話是抄的]

Cook1970年證明的一個理論得到,任何一個可以使用被稱為下推自動機的計算機抽象模型來解決的問題,也可以使用一個實際的計算機(更精確的說,使用一個隨機存取機)在與問題規(guī)模對應的時間內(nèi)解決。特別地,這個理論暗示存在著一個算法可以在大約m+n的時間內(nèi)解決模式匹配問題,這里mn分別是存儲文本和模式串數(shù)組的最大索引。Knuth Pratt努力地重建了 Cook的證明,由此創(chuàng)建了這個模式匹配算法。大概是同一時間,Morris在考慮設計一個文本編輯器的實際問題的過程中創(chuàng)建了差不多是同樣的算法。這里可以看到并不是所有的算法都是靈光一現(xiàn)中被發(fā)現(xiàn)的,而理論化的計算機科學確實在一些時候會應用到實際的應用中。

 

posted on 2009-08-10 15:50 baby-fly 閱讀(163) 評論(0)  編輯 收藏 引用 所屬分類: Algorithm
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99国产精品99久久久久久| 欧美色图麻豆| 国内精品久久久久久久影视蜜臀 | 国产综合色在线视频区| 1024亚洲| 日韩亚洲欧美中文三级| 久久精品国产2020观看福利| 在线观看欧美日韩国产| 久久av在线看| 国产亚洲aⅴaaaaaa毛片| 麻豆精品视频在线观看| 欧美一级网站| 在线一区亚洲| 亚洲影院在线观看| 亚洲第一搞黄网站| 亚洲国产精品999| 亚洲精品国久久99热| 午夜日韩av| 亚洲人成免费| 久久久久国产免费免费| 欧美在线一级va免费观看| 久久裸体艺术| 国产一区二区三区最好精华液| 欧美在线首页| 欧美三级资源在线| 一二三区精品福利视频| 久久午夜激情| 模特精品裸拍一区| 国产精品高潮在线| 欧美黄在线观看| 国语自产精品视频在线看抢先版结局 | 久久婷婷蜜乳一本欲蜜臀| 亚洲三级网站| 欧美日韩亚洲成人| 久久婷婷麻豆| 久久久精品五月天| 一区二区三区黄色| 亚洲私人影院在线观看| 欧美一二三区精品| 中文一区二区在线观看| 美女久久一区| 免费在线日韩av| 亚洲第一中文字幕在线观看| 久久久高清一区二区三区| 在线日韩成人| 欧美三级视频在线| 国产精品日韩一区二区三区| 久久激情婷婷| 午夜精彩视频在线观看不卡| 亚洲精品中文字幕在线| 亚洲精品视频免费在线观看| 欧美日韩福利视频| 欧美理论在线播放| 在线观看一区欧美| 国产日韩欧美一区在线| 欧美紧缚bdsm在线视频| 午夜亚洲性色福利视频| 美女91精品| 国产精品久久午夜夜伦鲁鲁| 国产精品激情av在线播放| 欧美专区在线观看一区| 最新中文字幕亚洲| 性久久久久久久| 久久亚洲春色中文字幕| 亚洲精选成人| 一区二区三区精品视频在线观看| 国产综合香蕉五月婷在线| 国产欧美欧洲在线观看| 欧美激情综合五月色丁香| 中日韩午夜理伦电影免费| 久久超碰97人人做人人爱| 亚洲第一区色| 99精品免费网| 日韩亚洲一区二区| 久久综合网络一区二区| 久久综合综合久久综合| 国产精品99久久久久久人| 午夜精品电影| 美女精品自拍一二三四| 亚洲专区在线视频| 欧美成人一品| 欧美四级伦理在线| 国产精品入口66mio| 国产亚洲欧美一区二区| 99成人在线| 午夜一级久久| 亚洲女人天堂av| 老司机一区二区三区| 一本色道久久88综合亚洲精品ⅰ| 亚洲小说欧美另类社区| 欧美大胆成人| 亚洲综合精品| 欧美成人性生活| 欧美亚洲午夜视频在线观看| 欧美—级在线免费片| 欧美日韩精品免费观看视一区二区 | 亚洲午夜日本在线观看| 欧美一级午夜免费电影| 亚洲毛片在线观看.| 欧美大片免费| 亚洲黄色免费| 亚洲天堂成人| 久久永久免费| 国产精品久久久久婷婷| 亚洲精品在线免费观看视频| 欧美激情麻豆| 亚洲青涩在线| 亚洲男女毛片无遮挡| 一本色道久久加勒比88综合| 欧美日本中文| 一区免费视频| 欧美**字幕| 欧美色精品天天在线观看视频| 国产日韩一区二区三区在线播放| 亚洲国产精品一区二区www在线| 久久裸体艺术| 欧美美女喷水视频| 午夜精品区一区二区三| 久久激情综合| 1024成人| 亚洲国产专区| 激情五月综合色婷婷一区二区| 久久亚洲国产精品一区二区 | 久久久久久国产精品mv| 欧美三级韩国三级日本三斤| 亚洲成人中文| 狠狠色狠狠色综合日日91app| 久久久久亚洲综合| 亚洲精品乱码久久久久久黑人 | 欧美一级一区| 欧美在线亚洲| 亚洲大胆人体视频| 一本色道久久精品| 欧美日韩亚洲三区| 久久精品91久久香蕉加勒比| 在线视频一区观看| 亚洲视频一二三| 久久夜色撩人精品| 欧美chengren| 伊人久久大香线蕉综合热线 | 欧美国产精品日韩| 亚洲福利在线观看| 欧美**字幕| 亚洲丰满在线| 亚洲国产美女久久久久| 国产免费亚洲高清| 久久精品国产99国产精品澳门 | 欧美a级理论片| 国产欧美在线播放| 久久天天综合| 久久久国产精彩视频美女艺术照福利| 99视频一区二区| 国产一区二区电影在线观看 | 亚洲网站在线观看| 日韩亚洲精品在线| 欧美一区二区大片| 一区二区三区视频免费在线观看| 国产精品国产三级国产普通话三级| 99综合在线| 性色av一区二区三区红粉影视| 极品av少妇一区二区| 麻豆国产精品一区二区三区| 亚洲午夜成aⅴ人片| 久久嫩草精品久久久精品| 另类专区欧美制服同性| 女同性一区二区三区人了人一| 免费高清在线一区| 牛牛国产精品| 免费永久网站黄欧美| 久久久免费av| 99视频精品全国免费| 牛牛影视久久网| 一本色道久久综合亚洲精品婷婷 | 亚洲伦理中文字幕| 国产精品va在线| 亚洲一区二区三区欧美 | 欧美午夜精品电影| 久久五月婷婷丁香社区| 久久久精品日韩| 午夜国产欧美理论在线播放| aa国产精品| 亚洲午夜精品网| 欧美中文在线观看| 欧美精品1区2区| 国产伦精品一区二区三区在线观看| 麻豆精品视频| 国产精品午夜在线观看| 欧美激情亚洲自拍| 国产亚洲一区二区三区在线播放| 91久久精品国产91性色tv| 国产午夜精品视频| 在线欧美亚洲| 亚洲国产婷婷| 麻豆国产精品777777在线| 欧美成人精品在线播放| 亚洲精品欧美日韩专区| 夜夜嗨一区二区| 亚洲先锋成人| 亚洲永久在线观看| 欧美日韩高清区|