第二題

GHOST_349178發表於2019-05-14
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAX 10000
#define MAX_LINES 100 

//P[0]不使用,P[i]表示B串的前i個字元中, 前P[i]個字元和後P[i]個字元相同 
int P[MAX]; //儘管strlen(b)為7,但P[7]用不到,只用P[1]到P[6]    

char* KMP(char* A, char* B);    //返回B串在A串中的位置 B串:模式串 A串:待匹配串 
void InitP(char *B);            //將B串(模式串)進行自我匹配 
char* strtolower(char *s)
{
  for(int i=0;i<sizeof(s);i++)
  {
    s[i]=tolower(s[i]);
  }
  return s;
}
int main()
{
  int mark=0;
  int lines=0;
  char pattern_o[MAX] = {};
  char pattern[MAX] = {};
  char strings_o[MAX_LINES][MAX]={};
  char strings[MAX_LINES][MAX]={};

  scanf("%s",&pattern_o);
  scanf("%d",&mark);
  scanf("%d",&lines);
  for(int i=0;i<lines;i++)
  {
    scanf("%s",&strings_o[i]);
  }
  if(mark==0)
  {
    for(int i=0;i<strlen(pattern_o);i++)
    {
      pattern[i] = tolower(pattern_o[i]);
    }
    for(int i=0;i<lines;i++)
    {
      for(int j=0;j<strlen(strings_o[i]);j++)
      {
        strings[i][j]=tolower(strings_o[i][j]);
      }
    }
  }
  else
  {
    for(int i=0;i<strlen(pattern_o);i++)
    {
      pattern[i] = pattern_o[i];
    }
    for(int i=0;i<lines;i++)
    {
      for(int j=0;j<strlen(strings_o[i]);j++)
      {
        strings[i][j]=strings_o[i][j];
      }
    }

  }
     InitP(pattern);
     for (int i=0;i<lines;i++)
     {
       char *idx=KMP(strings[i],pattern);
       if(idx)
       {
         printf("%s
",strings_o[i]);
       }

     }

     return 0;
}


char* KMP(char *A, char *B)
{
     int len1=strlen(A), len2=strlen(B);
     int i, j=0;                 //j代表目前B串中已與A串匹配了的字元的個數 
     for(i=0; i<len1; ++i)
     {
         while(j>0 && A[i]!=B[j])    //0...j-1,已匹配了j個字元,sub[j]是sub的第j+1的字元,因為下標從0開始
             j = P[j];

         if(A[i] == B[j]) 
             ++j;
         if(j == len2)              //當j(B中已匹配了的字串的個數)與B串本身長度相等時,說明匹配完畢 
             return A+i-j+1;        //此時可計算出指標位置 
     }
     return NULL;
}

void InitP(char *B)
{
     P[0] = 0;
     P[1] = 0;
     int i, j=0, len=strlen(B);
     for(i=2; i<len; ++i)
     {
         /*while(j>0 && B[j]!=B[i-1]), 這裡的j代表
        在比較第i個字元(從1開始數)和B[j]時,前i-1個字元中的前j個字元和後j的字元相同
        B[j]代表第j的字元(從1開始數)的下一個字元*/ 
         while(j>0 && B[j]!=B[i-1])  //如果第i個字元和第j個字元的下一個字元(即B[j])不同,則改變j的值,再重新比較
             j = P[j];                
         if(B[j] == B[i-1])  
             ++j;
         P[i] = j; 
     }    
}

相關文章