• 异或表达式运算


    本来要参加中兴的比赛的。可惜没有时间做了。

    用法:像正常的表达式一样。

    key1 and key2 and key3 如果key1 为false的话,后面的不再计算。

    key1 or key2 or key3 如果key1为true,后面的也不用再计算。

    支持括号。

    查找过滤时 用到了BM算法。
    #include<stack>
    #include <iostream>


    using namespace std;

    char buf[] = "123456789";


    /*
    函数:int* MakeSkip(char *, int)
    目的:根据坏字符规则做预处理,建立一张坏字符表
    参数:
    ptrn => 模式串P
    PLen => 模式串P长度
    返回:
    int* - 坏字符表
    */
    int* MakeSkip(char *ptrn, int pLen)

     int i;
     //为建立坏字符表,申请256个int的空间
     /*PS:之所以要申请256个,是因为一个字符是8位,
     所以字符可能有2的8次方即256种不同情况*/
     int *skip = (int*)malloc(256*sizeof(int));

     if(skip == NULL)
     {
      fprintf(stderr, "malloc failed!");
      return 0;
     } 

     //初始化坏字符表,256个单元全部初始化为pLen
     for(i = 0; i < 256; i++)
     {
      *(skip+i) = pLen;
     }

     //给表中需要赋值的单元赋值,不在模式串中出现的字符就不用再赋值了
     while(pLen != 0)
     {
      *(skip+(unsigned char)*ptrn++) = pLen--;
     }

     return skip;
    }


    /*
    函数:int* MakeShift(char *, int)
    目的:根据好后缀规则做预处理,建立一张好后缀表
    参数:
    ptrn => 模式串P
    PLen => 模式串P长度
    返回:
    int* - 好后缀表
    */
    int* MakeShift( char* ptrn,int pLen)
    {
     //为好后缀表申请pLen个int的空间
     int *shift = (int*)malloc(pLen*sizeof(int));
     int *sptr = shift + pLen - 1;//方便给好后缀表进行赋值的指标
     char *pptr = ptrn + pLen - 1;//记录好后缀表边界位置的指标
     char c;

     if(shift == NULL)
     {
      fprintf(stderr,"malloc failed!");
      return 0;
     }

     c = *(ptrn + pLen - 1);//保存模式串中最后一个字符,因为要反复用到它

     *sptr = 1;//以最后一个字符为边界时,确定移动1的距离

     pptr--;//边界移动到倒数第二个字符(这句是我自己加上去的,因为我总觉得不加上去会有BUG

    ,大家试试“abcdd”的情况,即末尾两位重复的情况)

     while(sptr-- != shift)//该最外层循环完成给好后缀表中每一个单元进行赋值的工作
     {
      char *p1 = ptrn + pLen - 2, *p2,*p3;

      //该do...while循环完成以当前pptr所指的字符为边界时,要移动的距离
      do{
       while(p1 >= ptrn && *p1-- != c);//该空循环,寻找与最后一个字符c匹配

    的字符所指向的位置

       p2 = ptrn + pLen - 2;
       p3 = p1;

       while(p3 >= ptrn && *p3-- == *p2-- && p2 >= pptr);//该空循环,判断在

    边界内字符匹配到了什么位置

      }while(p3 >= ptrn && p2 >= pptr);

      *sptr = shift + pLen - sptr + p2 - p3;//保存好后缀表中,以pptr所在字符为边界

    时,要移动的位置
      /*
      PS:在这里我要声明一句,*sptr = (shift + pLen - sptr) + p2 - p3;
      大家看被我用括号括起来的部分,如果只需要计算字符串移动的距离,那么括号中的那

    部分是不需要的。
      因为在字符串自左向右做匹配的时候,指标是一直向左移的,这里*sptr保存的内容,

    实际是指标要移动
      距离,而不是字符串移动的距离。我想SNORT是出于性能上的考虑,才这么做的。  

     
      */

      pptr--;//边界继续向前移动
     }

     return shift;
    }


    /*
    函数:int* BMSearch(char *, int , char *, int, int *, int *)
    目的:判断文本串T中是否包含模式串P
    参数:
    buf => 文本串T
    blen => 文本串T长度
    ptrn => 模式串P
    PLen => 模式串P长度
    skip => 坏字符表
    shift => 好后缀表
    返回:
    int - 1表示成功(文本串包含模式串),0表示失败(文本串不包含模式串)。
    */
    int BMSearch( char *ptrn,char *buf)
    {
     cout<<"ptrn  "<<ptrn<<endl;
     cout<<"buf  "<<buf<<endl;
     cout<<"--------------------"<<endl;
     int plen = strlen(ptrn);
     
     int b_idx = plen; 
     int blen = strlen(buf);
     

     if (plen == 0)
      return 0;
     if (plen == 1)
     {
      if (strchr(buf,ptrn[0]))
      {
       return 1;
      }
      else return 0;
     }
     int *skip  = MakeSkip(ptrn,plen);
     int *shift = MakeShift(ptrn,plen);

     while (b_idx <= blen)//计算字符串是否匹配到了尽头
     {
      int p_idx = plen, skip_stride, shift_stride;
      while (buf[--b_idx] == ptrn[--p_idx])//开始匹配
      {
       if (b_idx < 0)
        return 0;
       if (p_idx == 0)
       {    
        return 1;
       }
      }
      skip_stride = skip[(unsigned char)buf[b_idx]];//根据坏字符规则计算跳跃的距离
      shift_stride = shift[p_idx];//根据好后缀规则计算跳跃的距离
      b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;//取大者
     }
     return 0;
    }


    /**
    *0 not found
    *-1 expression illegal 
    *1 found
    */
    int judePtrStr(string & target,char* buf)
    {
     stack<string> opnd;//操作数
     stack<char>optr;//操作符
     stack<string>operate;//运算符
     bool restult = true;
     bool isUse = false;

     
     while (!target.empty())
     {
      //cout<<" 括号数 为"<<optr.size()<<endl;
      switch(target[0])
      {
      case ' ':
       {
        target.erase(0,1);
        break;
       }
      case '\"':
       {
        target.erase(0,1);
        size_t resultQuote = target.find('\"');
        if (string::npos != resultQuote )
        {
         string tempOpnd = target.substr(0,resultQuote);
         target.erase(0,resultQuote+1);
         
         opnd.push(tempOpnd);
         
         
        }
        else
        {
         return -1;
        }
        break;
       }
      case 'a':
       {
        string tempAnd = target.substr(0,3);
        
        if (tempAnd == "and")
        {
         target.erase(0,3);
         
         if (!opnd.empty())
         {
          string tempOpnd = opnd.top();
          opnd.pop();

          char   *p=new   char[tempOpnd.size()+1];
          strcpy(p,tempOpnd.c_str());
          
          if (!isUse)
          {
           restult = BMSearch(p,buf);
           isUse = true;
          }
          else
          {
           if (!operate.empty())
           {
            string tempOper =

    operate.top();
            if (tempOper == "and")
            {
             restult =BMSearch

    (p,buf)&&restult;
            }
            else restult =BMSearch

    (p,buf)||restult;
           }
           
          }
          delete p;
         }
         
         operate.push("and");
         if (!restult)
         {
          //删除元素,直到遇到or或 (,且or不在引号中
          int quoteNum=0;
          int bracketNum = 0;
          while (!target.empty())
          {
           
           if (target[0] =='\"' )
           {
            ++quoteNum;
           }
           else if (target[0] == '(')
           {
            ++bracketNum;
            optr.push('(');
           }
           else if (target[0] == ')')
           {
             bracketNum--;
            if (!optr.empty())
            {
             optr.pop();
            }
            else return -1;//括号不匹配
            
           }
           else if (target[0] ==

    'o'&&quoteNum%2 == 0&&bracketNum==0)
           {
            if (target[1] == 'r'&&

    (target[2]=='\"'||target[2] == ' '))
            {
             break;
            }
           }
           target.erase(0,1);
          }
         }
         
        }
        else
         return -1;//不是and 肯定非法
        
        break;

       }
      case 'o':
       {
        string tempAnd = target.substr(0,2);
        if (tempAnd == "or")
        {
         target.erase(0,2);
         
         if (!opnd.empty())
         {
          

          string tempOpnd = opnd.top();
          opnd.pop();

          char   *p=new   char[tempOpnd.size()+1];
          strcpy(p,tempOpnd.c_str());

          if (!isUse)
          {
           restult = BMSearch(p,buf);
           isUse = true;
          }
          else
           if (!operate.empty())
           {
            string tempOper =

    operate.top();
            if (tempOper == "and")
            {
             restult =BMSearch

    (p,buf)&&restult;
            }
            else restult =BMSearch

    (p,buf)||restult;
           }
          delete p;
         }
         
         operate.push("or");
         
         if (restult)
         {
          //删除元素,直到遇到),且)不在引号中
          int quoteNum=0;
          int bracketNum = 0;
          while (!target.empty())
          {

           if (target[0] =='\"' )
           {
            ++quoteNum;
           }
            else if (target[0] == '(')
            {
             bracketNum++;
            }
           else if (target[0] ==

    ')'&&quoteNum%2 == 0)
           {
            //target.erase(0,1);
            if (bracketNum == 0)
            {
             break;
            }
            else bracketNum--;
            

           }
           target.erase(0,1);
          }
         }
         
        }
        else
         return -1;//不是or 非法    

        break;

       }
      case '(':
       {
        optr.push('(');
        target.erase(0,1);
        break;
       }
      case ')':
       {
        target.erase(0,1);
        if (optr.empty())
        {
         return -1;
        }
        char c = optr.top();;    
        
        if ( c != '(')
        {
         return -1;//括号不匹配
        }
        else optr.pop();
        break;
       }
      default:
       return -1;//参数非法,未知类型
      }
      
     }
     
     if (!opnd.empty())
     {
      string tempOpnd = opnd.top();
      opnd.pop();
      
      char   *p=new   char[tempOpnd.size()+1];
      strcpy(p,tempOpnd.c_str());

      restult =BMSearch(p,buf);//此处不能直接返回有可能有括号不匹配的情况
      delete p;
      
     }
     if (!optr.empty())
     {
      return -1;//括号不匹配
     }
     return restult;

    }


    int main()
    {/*
     string cc = "\"7\"and \"23\"and\"1\"or \"a\"";
     string cc = "\"7\"and \"a\"and\"1\"or \"a\"";
     string cc = "\"7\"or \"a\"and\"1\"or \"a\"";
     string cc = "(\"7\"or \"1\")and\"a\"";
     string cc = "\"7\"and \"1\"and\"a\"";
     string cc = "(\"7\"and \"1\")and\"a\"";
     string cc = "\"7\"and (\"1\"or\"a\")";
     string cc = "\"a\"and (\"1\"or\"a\")";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"l\")";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"4\")";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"4\"";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"4\"and\"l\"";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"4\"and\"2\"and\"3\"and\"5\"and\"6\"and\"7

    \"and\"0\"";
     string cc = "\"a\"or ((\"1\"or\"a\")and\"4\"and\"2\"and\"3\"and\"5\"and\"6\"and\"7

    \"and\"8\"";
     string cc = "(((\"a\"or ((\"1\"or\"a\"))or\"2\")or\"3\")and(\"4\"and\"5\")";
     string cc = "(((\"a\"or ((\"1\"or\"a\"))or\"2\")or\"3\")and(\"4\"and\"5\"))";
     string cc = "(((\"a\"or ((\"1\"or\"a\"))or\"2\")or\"3\")and(\"4\"and\"0\")";
     string cc = "(((\"a\"or ((\"1\"or\"a\"))or\"2\")or\"3\")and(\"4\"and\"0\"))or\"p\"";
     string cc = "(((\"a\"or ((\"1\"or\"a\"))or\"2\")or\"3\")and((\"4\"and\"0\"))

    or\"p\")";
     string cc = "(((\"a\"and ((\"1\"or\"c\"))or\"2\")or\"3\")and(\"4\"and\"0\"))

    or\"p\"";
     string cc = ")))";
     string cc = "())";*/
     //string cc = "(((\"a\"and ((\"1\"or\"c\"))or\"2\")or\"3\")and(\"R\"and\"0\"))

    or\"p\"";

     /*string buf1 = "Ncp Recveive Message From Smcc: CmdCode = 0x5006,lParamLen =

    0x0.";*/

     string buf1 = "Ncp Send Message To Mcu:  nMcuAdrs=0x 10301 CmdCode =

    0x11ab,lParamLen = 0x12.\n"
      "--------- NCP TO MCU ---------- The Content of Message Buffer is: \n"
     "01  03  01  01  12  01  ff  ff  ff  fe  ff  ff  ff  fe  11  ab  fe  01  fe  fe  00 

    00  00  12  00  01 \n"
      "01  12  01  fe  fe  fe  00  01  00  01  02  02  fe  fe  fe  fe  fe  fe\n"
      "Set the(slot:3 port:1) device type:ETHERNET\n"
      "Comm process(0) send msg to Smcc(192.192.1.5) successfully! CmdCode:

    0x5006\n";

    char *p1 = new char[buf1.size()+1];
     strcpy(p1,buf1.c_str());
     
     /*string ptrn = "\"Ncp\" and \"Send\" or \"core\"";
     string ptrn = "\"Ncp\" and \"core\"";

     string ptrn = "(\"Ncp\" or \"core\")and \"Message\"and \"core\"";

     string ptrn = "(\"Ncp\" or \"core\")and \"Message\"or \"core\"";
     string ptrn = "((\"Ncp\" or \"core\")and \"Message\"or \"core\")and\"core\"";*/
     string ptrn = "((\"Ncp\" and \"core\")and \"Message\"or \"core\")and\"core\"";
     
      
      int resutl = judePtrStr(ptrn,p1);
      cout<<"============buf1 begin==============="<<endl;
      if (resutl == 1)
      {
       cout<<buf1<<endl;
      }
      cout<<"============buf1 end==============="<<endl;

    system("pause");

     
    }

  • 相关阅读:
    gcc和g++的区别
    configure svn server on win
    FD_SET,FD_ISSET,FD_ZERO,select
    intel中的cr寄存器
    Linux系统环境下的Socket编程详细解析
    可重入函数与不可重入函数
    初步认识迭代服务器和并发服务器
    排序
    fd_set 用法
    MFC消息映射
  • 原文地址:https://www.cnblogs.com/corecible/p/1761264.html
Copyright © 2020-2023  润新知