国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C/C++實現字符串模糊匹配

2020-05-23 14:06:00
字體:
來源:轉載
供稿:網友
本文分別給大家介紹了2個C++在Linux平臺和windows平臺下實現字符串模糊匹配的方法,基本的核心思想都是一樣的,均是使用fnmatch函數,有需要的小伙伴可以參考下。
 

需求:

  準入授權配置文件有時候分了好幾個維度進行配置,例如 company|product|sys這種格式的配置:

1.配置 "sina|weibo|pusher" 表示 sina公司weibo產品pusher系統能夠準入,而"sina|weibo|sign"不允許準入

2.配置 "sina|*|pusher” 表示sina公司所有產品的pusher系統都能夠準入

3.配置 “*|*|pusher” 表示所有公司的所有產品的pusher系統都能夠準入

  …

  類似還有很多場景,好了,簡單的東西不扯蛋了.

實現:

  面對這個需求我第一時間想的是如何設計模式串,如何快速實現功能,因為我現在寫的是一個C服務,所以我首先出現在我腦海的是一大堆strchr(XXX, ‘*'), strchr(XXX, ‘|')等等東西,后面發現這個東西沒有必要自己造輪子,有現成的函數可以用,那就是fnmatch.

  google了一下,發現fnmatch的資料并不是很多,大部分還都是講php函數的,所以沒辦法,只能自己寫寫測測了.

#include <iostream>#include <fnmatch.h>#include <vector>using namespace std; int main(){  const char* orgin_str = "sina|weibo|pusher";  char pattern_arr[][20] = {    {"sina|*|pusher"},    {"sina|*|*"},    {"*|weibo|*"},    //不能被匹配的    {"sina|pic|*"},    {"*|*|sign"},    {"*|weibo|sign"},    {"*|pic|sign"},    {"sina|pic|sign"},     {"*|*|*"}  };  static int pattern_arr_size = sizeof(pattern_arr) / sizeof(pattern_arr[0]);   vector<char *> vec_str;  for(int i = 0; i < pattern_arr_size; i ++)  {    vec_str.push_back(pattern_arr[i]);  }   int ret;  int z = 0;  while(z < 1){    for(int i = 0; i < vec_str.size(); i++)    {         ret = fnmatch(vec_str.at(i), orgin_str, FNM_PATHNAME);      if(FNM_NOMATCH == ret){        cout<<"sorry I'm failed ["<< vec_str.at(i) <<"]"<<endl;      }       }       ++z;    }}

結果:   

  實驗一把,結果還不賴,完全滿足需求:

C++,字符串,模糊匹配

  需求滿足了,我擔心的還有一個問題,那就是性能,注釋掉cout輸出,將while z語句調至1,000,000,重新編譯跑一下:

  time ./fnmatch

C++,字符串,模糊匹配

看來效率還不錯,2.1s 進行了100W次匹配,平均2us一次,性能要求也滿足了...

附:上面文章只介紹了在Linux系統下直接調用系統函數fnmatch即可實現,而沒有考慮在Windows在的使用。

本人這周看了下Google-glog代碼,恰巧發現了一個類似fnmatch的簡單實現,因此綜合起來提供了一個跨平臺的接口。

#ifdef OS_WINDOWS/* Bits set in the FLAGS argument to `fnmatch'. copy from fnmatch.h(linux) */#define  FNM_PATHNAME  (1 << 0) /* No wildcard can ever match `/'. */#define  FNM_NOESCAPE  (1 << 1) /* Backslashes don't quote special chars. */#define  FNM_PERIOD    (1 << 2) /* Leading `.' is matched only explicitly. */#define  FNM_NOMATCH    1#define fnmatch fnmatch_win/**copy from Google-glog*/bool SafeFNMatch(const char* pattern,size_t patt_len,const char* str,size_t str_len){  size_t p = 0;  size_t s = 0;  while (1)  {    if (p == patt_len && s == str_len)      return true;    if (p == patt_len)      return false;    if (s == str_len)      return p+1 == patt_len && pattern[p] == '*';    if (pattern[p] == str[s] || pattern[p] == '?')    {      p += 1;      s += 1;      continue;    }    if (pattern[p] == '*')    {      if (p+1 == patt_len) return true;      do      {        if (SafeFNMatch(pattern+(p+1), patt_len-(p+1), str+s, str_len-s))        {          return true;        }        s += 1;      } while (s != str_len);      return false;    }    return false;  }}/**注意:Windows平臺下尚未實現最后一個參數flags的功能!!!*/int fnmatch_win(const char *pattern, const char *name, int flags = 0){  if(SafeFNMatch(pattern,strlen(pattern),name,strlen(name)))    return 0;  else    return FNM_NOMATCH;}#else#include <fnmatch.h>#endifint main(){  const char* orgin_str = "sina|weibo|pusher";  char pattern_arr[][20] = {    {"sina|*|pusher"},    {"sina|*|*"},    {"*|weibo|*"},    //不能被匹配的    {"sina|pic|*"},    {"*|*|sign"},    {"*|weibo|sign"},    {"*|pic|sign"},    {"sina|pic|sign"},    {"*|*|*"}  };  static int pattern_arr_size = sizeof(pattern_arr) / sizeof(pattern_arr[0]);  vector<char *> vec_str;  for(int i = 0; i < pattern_arr_size; i ++)  {    vec_str.push_back(pattern_arr[i]);  }  std::cout << "Origin Str: " << orgin_str << "/n/n";  int ret;  for(int i = 0; i < vec_str.size(); i++)  {    ret = fnmatch(vec_str.at(i), orgin_str, FNM_PATHNAME);    if(ret == FNM_NOMATCH)    {      cout<<"sorry, I'm failed: ["<< vec_str.at(i) <<"]/n";    }    else    {      cout<<"OK, I'm success: ["<< vec_str.at(i) <<"]/n";    }  }  return 0;}

輸出如下:

C++,字符串,模糊匹配



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 北辰区| 攀枝花市| 沈阳市| 阜宁县| 阿勒泰市| 黄浦区| 八宿县| 庆城县| 西充县| 灵川县| 威远县| 丽水市| 肃南| 文昌市| 思茅市| 甘南县| 枣阳市| 阿图什市| 铁岭市| 昌图县| 洞头县| 玉田县| 新丰县| 梓潼县| 宁陵县| 韶山市| 墨脱县| 武汉市| 垣曲县| 克什克腾旗| 射洪县| 紫云| 乌拉特后旗| 崇义县| 玛多县| 温泉县| 霍山县| 巴林右旗| 林西县| 当涂县| 平舆县|