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

為生存而奔跑

   :: 首頁 :: 聯系 :: 聚合  :: 管理
  271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

留言簿(5)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 331736
  • 排名 - 74

最新評論

閱讀排行榜

評論排行榜

KMP字符串模式匹配通俗點說就是一種在一個字符串中定位另一個串的高效算法。簡單匹配算法的時間復雜度為O(m*n);KMP匹配算法。可以證明它的時間復雜度為O(m+n).。
. 簡單匹配算法
先來看一個簡單匹配算法的函數:
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 ++; // 繼續比較后一字符
else
{
i ++; j = 0; // 重新開始新的一輪匹配
}
if ( T[j] == '\0')
return i; // 匹配成功   返回下標
else
return -1; // 串S中(第pos個字符起)不存在和串T相同的子串
} // Index_BF
   此 算法的思想是直截了當的:將主串S中某個位置i起始的子串和模式串T相比較。即從 j=0 起比較 S[i+j] 與 T[j],若相等,則在主串 S 中存在以 i 為起始位置匹配成功的可能性,繼續往后比較( j逐步增1 ),直至與T串中最后一個字符相等為止,否則改從S串的下一個字符起重新開始進行下一輪的"匹配",即將串T向后滑動一位,即 i 增1,而 j 退回至0,重新開始新一輪的匹配。
例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我們可以假設從下標0開始):先是比較S[0]和T[0]是否相等,然后比較S[1] 和T[1]是否相等…我們發現一直比較到S[5] 和T[5]才不等。如圖:
 
當這樣一個失配發生時,T下標必須回溯到開始,S下標回溯的長度與T相同,然后S下標增1,然后再次比較。如圖:
這次立刻發生了失配,T下標又回溯到開始,S下標增1,然后再次比較。如圖:
這次立刻發生了失配,T下標又回溯到開始,S下標增1,然后再次比較。如圖:


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

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



KMP匹配算法和簡單匹配算法效率比較,一個極端的例子是:
在S=“AAAAAA…AAB“(100個A)中查找T=”AAAAAAAAAB”, 簡單匹配算法每次都是比較到T的結尾,發現字符不同,然后T的下標回溯到開始,S的下標也要回溯相同長度后增1,繼續比較。如果使用KMP匹配算法,就不必回溯.
對于一般文稿中串的匹配,簡單匹配算法的時間復雜度可降為O (m+n),因此在多數的實際應用場合下被應用。
KMP 算法的核心思想是利用已經得到的部分匹配信息來進行后面的匹配過程。看前面的例子。為什么T[5]==’d’的模式函數值等于2(next[5]=2), 其實這個2表示T[5]==’d’的前面有2個字符和開始的兩個字符相同,且T[5]==’d’不等于開始的兩個字符之后的第三個字符 (T[2]=’c’).如圖:
也就是說,如果開始的兩個字符之后的第三個字符也為’d’,那么,盡管T[5]==’d’的前面有2個字符和開始的兩個字符相同,T[5]==’d’的模式函數值也不為2,而是為0。
   前面我說:在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,當第一次搜索到S[5] 和T[5]不等后,S下標不是回溯到1,T下標也不是回溯到開始,而是根據T中T[5]==’d’的模式函數值,直接比較S[5] 和T[2]是否相等。。。為什么可以這樣?
剛 才我又說:“(next[5]=2),其實這個2表示T[5]==’d’的前面有2個字符和開始的兩個字符相同”。請看圖 :因為,S[4] ==T[4],S[3] ==T[3],根據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]是根據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]時,發現不等,就去看next[2]的值,next[2]=-1,意思是S[2]已經和T[0] 間接比較過了,不相等,接下來去比較S[3]和T[0]吧。
假設S不變,在S中搜索T=“abbabd”呢?答:這種情況當比較到S[2]和T[2]時,發現不等,就去看next[2]的值,next[2]=0,意思是S[2]已經和T[2]比較過了,不相等,接下來去比較S[2]和T[0]吧。
假 設S=”abaabcabdabba”在S中搜索T=“abaabd”呢?答:這種情況當比較到S[5]和T[5]時,發現不等,就去看next[5]的 值,next[5]=2,意思是前面的比較過了,其中,S[5]的前面有兩個字符和T的開始兩個相等,接下來去比較S[5]和T[2]吧。
總之,有了串的next值,一切搞定。那么,怎么求串的模式函數值next[n]呢?(本文中next值、模式函數值、模式值是一個意思。)
. 怎么求串的模式值 next[n]
定義
(1)next[0]= -1 意義:任何串的第一個字符的模式值規定為-1。
(2)next[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]
(3)next[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”的模式函數的值。
     next[0]= -1 根據(1)
     next[1]=0   根據 (4)   因(3)有1<=k<j;不能說,j=1,T[j-1]==T[0]
     next[2]=0   根據 (4)   因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)
     next[3]= -1 根據 (2)
     next[4]=1   根據 (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], 根據 (3)” 且T[j] != T[k]”被劃入(4)。
02)來個復雜點的,求T=”ababcaabc” 的模式函數的值。
next[0]= -1    根據(1)
         next[1]=0    根據(4)
         next[2]=-1   根據 (2)
next[3]=0   根據 (3) 雖T[0]=T[2] 但T[1]=T[3] 被劃入(4)
next[4]=2   根據 (3) T[0]T[1]=T[2]T[3] 且T[2] !=T[4]
next[5]=-1 根據 (2) 
next[6]=1   根據 (3) T[0]=T[5] 且T[1]!=T[6]
next[7]=0   根據 (3) 雖T[0]=T[6] 但T[1]=T[7] 被劃入(4)
next[8]=2   根據 (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,而不是=1,next[6]=1,而不是= -1,next[8]=2,而不是= 0,其他的好象都容易理解。
03)   來個特殊的,求 T=”abCabCad” 的模式函數的值。
下標
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 根據 (3) 雖T[0]T[1]=T[3]T[4],但T[2]==T[5]
next[6]= -1 根據 (2) 雖前面有abC=abC,但T[3]==T[6]
next[7]=4   根據 (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” 的模式函數值,并用后面的求模式函數值函數驗證。
意義
 next 函數值究竟是什么含義,前面說過一些,這里總結。
設在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函數值next[n],
1.       next[n]= -1 表示S[m]和T[0]間接比較過了,不相等,下一次比較 S[m+1] 和T[0]
2.       next[n]=0 表示比較過程中產生了不相等,下一次比較 S[m] 和T[0]。
3.       next[n]= k >0 但k<n, 表示,S[m]的前k個字符與T中的開始k個字符已經間接比較相等了,下一次比較S[m]和T[k]相等嗎?
4.       其他值,不可能。
. 求串 T 的模式值 next[n] 的函數
說了這么多,是不是覺得求串T的模式值next[n]很復雜呢?要叫我寫個函數出來,目前來說,我寧愿去登天。好在有現成的函數,當初發明KMP算法,寫出這個函數的先輩,令我佩服得六體投地。我等后生小子,理解起來,都要反復琢磨。下面是這個函數:
void get_nextval(const char *T, int next[])
{
       // 求模式串T的next函數值并存入數組 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模式匹配程序,各位可以用他驗證。記得加入上面的函數
#include <iostream.h>
#include <string.h>
int KMP(const char *Text,const char* Pattern) //const 表示函數內部不會改變這個參數的值。
{
       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);//求Pattern的next函數值
   
       int index=0,i=0,j=0;
       while(Text[i]!='\0' && Pattern[j]!='\0' )
       {
              if(Text[i]== Pattern[j])
              {
                     ++i;// 繼續比較后繼字符
                     ++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;
}
五.其他表示模式值的方法
上 面那種串的模式值表示方法是最優秀的表示方法,從串的模式值我們可以得到很多信息,以下稱為第一種表示方法。第二種表示方法,雖然也定義next[0]= -1,但后面絕不會出現-1,除了next[0],其他模式值next[j]=k(0≤k<j)的意義可以簡單看成是:下標為j的字符的前面最多k 個字符與開始的k個字符相同,這里并不要求T[j] != T[k]。其實next[0]也可以定義為0(后面給出的求串的模式值的函數和串的模式匹配的函數,是next[0]=0的),這 樣,next[j]=k(0≤k<j)的意義都可以簡單看成是:下標為j的字符的前面最多k個字符與開始的k個字符相同。第三種表示方法是第一種表 示方法的變形,即按第一種方法得到的模式值,每個值分別加1,就得到第三種表示方法。第三種表示方法,我是從論壇上看到的,沒看到詳細解釋,我估計是為那 些這樣的編程語言準備的:數組的下標從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 。
從 這里我們可以看到:串的模式值第一種表示方法能表示更多的信息,第二種表示方法更單純,不容易搞錯。當然,用第一種表示方法寫出的模式匹配函數效率更高。 比如說,在串S=“adCadCBdadCadCad 9876543”中匹配串T=“adCadCad”, 用第一種表示方法寫出的模式匹配函數,當比較到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]吧。如果用第二種表示方法寫出的模式匹配函數,當比較到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]。是不是比用第一種表示方法寫出的模式匹配函數多繞了幾個 彎。
為什么,在講明第一種表示方法后,還要講沒有第一種表示方法好的第二種表示方法?原因是:最開始,我看嚴蔚敏的一個講座,她給出的模式值表示方法是我這里的第二種表示方法,如圖:
她 說:“next 函數值的含義是:當出現S[i] !=T[j]時,下一次的比較應該在S[i]和T[next[j]] 之間進行。”雖簡潔,但不明了,反復幾遍也沒明白為什么。而她給出的算法求出的模式 值是我這里說的第一種表示方法next值,就是前面的get_nextval()函數。匹配算法也是有瑕疵的。于是我在這里發帖說她錯了:
   現在看來,她沒有錯,不過有張冠李戴之嫌。我不知道,是否有人第一次學到這里,不參考其他資料和明白人講解的情況下,就能搞懂這個算法(我的意思是不僅是 算法的大致思想,而是為什么定義和例子中next[j]=k(0≤k<j),而算法中next[j]=k(-1≤k<j))。憑良心說:光看 這個講座,我就對這個教受十分敬佩,不僅講課講得好,聲音悅耳,而且這門課講得層次分明,恰到好處。在KMP這個問題上出了點小差錯,可能是編書的時候, 在這本書上抄下了例子,在那本書上抄下了算法,結果不怎么對得上號。因為我沒找到原書,而據有的網友說,書上已不是這樣,也許吧。說起來,教授們研究的問 題比這個高深不知多少倍,哪有時間推演這個小算法呢。總之,瑕不掩玉。
書歸正傳,下面給出我寫的求第二種表示方法表示的模式值的函數,為了從S的任何位置開始匹配T,“當出現S[i] !=T[j]時,下一次的比較應該在S[i]和T[next[j]] 之間進行。”    定義next[0]=0 。
 void myget_nextval(const char *T, int next[])
{
     // 求模式串T的next函數值(第二種表示方法)并存入數組 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
 
下面是模式值使用第二種表示方法的匹配函數(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; // 繼續比較后繼字符
     }
   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];     /*當出現S[i] !=T[j]時,
              下一次的比較應該在S[i]和T[next[j]] 之間進行。要求next[0]=0。
在這兩個簡單示范函數間使用全局數組next[]傳值。*/
   }
}//while
if ( T[j] == '\0' )
    return (i-j); // 匹配成功
else
     return -1;
} // my_KMP
六.后話 --KMP 的歷史
[這段話是抄的]
Cook 于1970年證明的一個理論得到,任何一個可以使用被稱為下推自動機的計算機抽象模型來解決的問題,也可以使用一個實際的計算機(更精確的說,使用一個隨 機存取機)在與問題規模對應的時間內解決。特別地,這個理論暗示存在著一個算法可以在大約m+n的時間內解決模式匹配問題,這里m和n分別是存儲文本和模 式串數組的最大索引。Knuth 和Pratt努力地重建了 Cook的證明,由此創建了這個模式匹配算法。大概是同一時間,Morris在考慮設計一個文本編輯器的實際問題的過程中創建了差不多是同樣的算法。這里 可以看到并不是所有的算法都是“靈光一現”中被發現的,而理論化的計算機科學確實在一些時候會應用到實際的應用中。
posted on 2010-08-04 07:36 baby-fly 閱讀(638) 評論(1)  編輯 收藏 引用 所屬分類: Algorithm

Feedback

# re: KMP字符串模式匹配詳解 2010-12-11 22:09 sll
幸苦了  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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在线|亚洲一区二区| 葵司免费一区二区三区四区五区| 欧美视频在线免费| 亚洲日本va午夜在线电影| 欧美国产高潮xxxx1819| 午夜精品久久久久久久久久久| 欧美交受高潮1| 日韩亚洲在线观看| 亚洲制服av| 国产一区再线| 亚洲人成在线观看网站高清| 欧美成年人视频| 洋洋av久久久久久久一区| aaa亚洲精品一二三区| 国产精品一卡二| 欧美成人日韩| 国产精品美女www爽爽爽| 欧美亚洲网站| 蜜桃精品久久久久久久免费影院| 亚洲激情视频| 亚洲欧美韩国| 日韩视频二区| 噜噜噜噜噜久久久久久91 | 136国产福利精品导航网址| 亚洲人成人一区二区三区| 国内一区二区三区| 一区二区三区国产在线| 一区二区精品| 欧美日本一区二区视频在线观看| 久久亚洲私人国产精品va| 国产精品伊人日日| 亚洲欧美综合网| 亚洲影视综合| 国产精品久久久久99| 日韩午夜在线电影| 蜜桃av一区| 久久精品国产99国产精品| 欧美午夜精品久久久久免费视| 亚洲欧洲精品一区二区三区不卡 | 国内成人在线| 欧美尤物一区| 久久精品国产一区二区电影 | 亚洲综合国产精品| 欧美午夜在线一二页| 亚洲一区国产精品| 久久精品水蜜桃av综合天堂| 国产午夜精品全部视频在线播放| 亚洲欧美另类国产| 久久永久免费| 一本一本a久久| 国产精品欧美激情| 久久免费视频在线| 99精品国产在热久久| 久久国产综合精品| 亚洲精品一区二区三区不| 欧美日韩影院| 欧美电影打屁股sp| 亚洲综合色婷婷| 欧美丰满高潮xxxx喷水动漫| 在线天堂一区av电影| 国产性猛交xxxx免费看久久| 欧美成人国产一区二区| 午夜精品av| 日韩一二在线观看| 欧美激情第8页| 久久看片网站| 国产精品一区二区a| 免费的成人av| 亚洲欧美激情一区二区| 夜夜爽av福利精品导航| 亚洲成在线观看| 久久综合影视| 久久免费国产精品| 久久九九免费| 午夜精品短视频| 亚洲视频播放| 亚洲一区免费在线观看| 亚洲深夜福利视频| 一区二区久久久久久| 亚洲一区中文| 欧美亚洲免费电影| 午夜在线精品| 久久精品亚洲一区二区三区浴池 | 欧美大片免费观看在线观看网站推荐| 亚洲影视九九影院在线观看| 亚洲一区自拍| 久久精品视频在线看| 你懂的一区二区| 欧美高清在线观看| 亚洲美女在线一区| 亚洲欧美在线免费| 久久久久久夜| 国产精品黄色在线观看| 国产午夜精品理论片a级探花| 国产一区二区毛片| 夜夜爽99久久国产综合精品女不卡| 99国产精品| 午夜影院日韩| 亚洲欧洲在线看| 久久久成人网| 欧美日韩一区二区三区高清| 国产一区二区中文字幕免费看| 亚洲高清不卡一区| 久久久91精品国产一区二区三区| 欧美成人性生活| 亚洲欧美日韩精品久久| 亚洲国产精品久久久久| 亚洲另类视频| 免费中文字幕日韩欧美| 国产视频自拍一区| 亚洲视频在线观看网站| 亚洲激情不卡| 欧美va亚洲va香蕉在线| 国产自产v一区二区三区c| 亚洲在线日韩| 亚洲一区二区网站| 国产丝袜一区二区| 久久久久久久一区| 亚洲欧美中文另类| 国产精品少妇自拍| 亚洲欧美日韩精品久久奇米色影视 | 国色天香一区二区| 久久九九国产| 久久精品一区中文字幕| 国产亚洲综合在线| 久久午夜精品| 欧美久久影院| 亚洲一区久久久| 亚洲网友自拍| 国产午夜精品久久久久久久| 免费久久精品视频| 欧美日韩国产在线| 午夜在线精品偷拍| 久久精品国产免费| 亚洲午夜久久久久久久久电影院 | 欧美一区二区视频97| 性欧美video另类hd性玩具| 黑人一区二区三区四区五区| 亚洲福利国产精品| 国产精品热久久久久夜色精品三区| 久久精品国内一区二区三区| 亚洲精品视频在线播放| 久久久综合网站| 午夜电影亚洲| 久久久久88色偷偷免费| 在线一区视频| 欧美精品videossex性护士| 午夜亚洲性色福利视频| 免费亚洲网站| 久久久久久久久蜜桃| 欧美三区在线| 日韩午夜在线播放| 99热在线精品观看| 久久综合久久综合这里只有精品| 亚洲欧美日韩国产综合| 欧美破处大片在线视频| 欧美大片一区二区| 激情久久久久久久| 性视频1819p久久| 亚洲一区精品电影| 欧美少妇一区二区| av72成人在线| 午夜伦理片一区| 国产精品伦一区| 在线亚洲观看| 欧美一区二区三区免费看| 国产欧美va欧美不卡在线| 亚洲直播在线一区| 久久九九免费视频| 亚洲国产另类久久精品| 免费成人美女女| 欧美激情一区二区| 亚洲欧美一区二区视频| 国产精品久久久久9999高清| 亚洲午夜精品久久久久久app| 性欧美大战久久久久久久免费观看| 国产精品香蕉在线观看| 久久午夜电影网| 99精品国产高清一区二区 | 亚洲精品综合| 亚洲欧洲日夜超级视频| 黄色日韩网站| 亚洲免费av片| 亚洲第一精品久久忘忧草社区| 免播放器亚洲一区| 国产农村妇女毛片精品久久莱园子 | 老司机午夜精品视频| 欧美日韩一区二区三区在线看 | 欧美区一区二区三区| 亚洲国产欧美国产综合一区| 亚洲一区二区三区乱码aⅴ| 国产一区二区精品| 欧美性开放视频| 美女999久久久精品视频| 99这里只有久久精品视频| 欧美大片在线看| 蜜桃久久精品乱码一区二区| 亚洲欧美在线播放| 99在线热播精品免费| 亚洲国产经典视频|