zoukankan      html  css  js  c++  java
  • nyoj 题目5 Binary String Matching

    Binary String Matching

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:3
     
    描述
    Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should output 3, because the pattern A appeared at the posit
     
    输入
    The first line consist only one integer N, indicates N cases follows. In each case, there are two lines, the first line gives the string A, length (A) <= 10, and the second line gives the string B, length (B) <= 1000. And it is guaranteed that B is always longer than A.
    输出
    For each case, output a single line consist a single integer, tells how many times do B appears as a substring of A.
    样例输入
    3
    11
    1001110110
    101
    110010010010001
    1010
    110100010101011 
    样例输出
    3
    0
    3 

    此题第一感觉就是用KMP算法,代码如下
     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 char a[12];
     5 char b[1002];
     6 int next[12];
     7 
     8 void getNext() {
     9     next[0] = -1;
    10     int len = strlen(a);
    11     int i = 0,j = -1;
    12     while(i < len) {
    13         if(j == -1 || a[i] == a[j]) {
    14             i++,j++;
    15             next[i] = j;
    16         }
    17         else {
    18             j = next[j];
    19         }
    20     }
    21 }
    22 
    23 int calCnt() {
    24     int at = 0;
    25     int bt = 0;
    26     int ans = 0;
    27     int lena = strlen(a);
    28     int lenb = strlen(b);
    29     while(bt < lenb) {
    30         if(at == -1 || a[at] == b[bt]) {
    31             at++;
    32             bt++;
    33             if(at == lena) {
    34                 ans++;
    35                 at = next[lena];
    36             }
    37             continue;
    38         }
    39         if(a[at] != b[bt]) {
    40             at = next[at];
    41         }
    42 
    43     }
    44     return ans;
    45 }
    46 
    47 int main(int argc, char const *argv[])
    48 {
    49     int n;
    50     while(scanf("%d",&n) != EOF) {
    51         while(n--) {
    52             scanf("%s",a);
    53             scanf("%s",b);
    54             getNext();
    55             int ans = calCnt();
    56             printf("%d
    ", ans);
    57         }
    58     }
    59     return 0;
    60 }

    此算法第一要求出next数组。而求next数组的过程本身也是一个自己和自己匹配的过程。此处用i不断前进,j不断返回,用作匹配。

    计数时是新的匹配过程。和求next数组的过程神似。

    若求nextval数组可能会更快些,代码如下

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 char a[12];
     5 char b[1002];
     6 int nextval[12];
     7 
     8 void getnextval() {
     9     nextval[0] = -1;
    10     int len = strlen(a);
    11     int i = 0,j = -1;
    12     while(i < len) {
    13         if(j == -1 || a[i] == a[j]) {
    14             i++,j++;
    15             if(i < len && a[i] == a[j]) {
    16                 nextval[i] = nextval[j];
    17             }
    18             else {
    19                 nextval[i] = j;
    20             }
    21             
    22         }
    23         else {
    24             j = nextval[j];
    25         }
    26     }
    27 }
    28 
    29 int calCnt() {
    30     int at = 0;
    31     int bt = 0;
    32     int ans = 0;
    33     int lena = strlen(a);
    34     int lenb = strlen(b);
    35     while(bt < lenb) {
    36         if(at == -1 || a[at] == b[bt]) {
    37             at++;
    38             bt++;
    39             if(at == lena) {
    40                 ans++;
    41                 at = nextval[lena];
    42             }
    43             continue;
    44         }
    45         if(a[at] != b[bt]) {
    46             at = nextval[at];
    47         }
    48 
    49     }
    50     return ans;
    51 }
    52 
    53 int main(int argc, char const *argv[])
    54 {
    55     int n;
    56     while(scanf("%d",&n) != EOF) {
    57         while(n--) {
    58             scanf("%s",a);
    59             scanf("%s",b);
    60             getnextval();
    61             int ans = calCnt();
    62             printf("%d
    ", ans);
    63         }
    64     }
    65     return 0;
    66 }

    要注意15行的条件。但实际运行好像并没有更快。

    今天偶然发现nyoj可以查看优秀的代码,这一点简直完爆其他oj,看到这样一种非常取巧的办法

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 int main(int argc, char const *argv[])
     6 {
     7     string s1,s2;
     8     int n;
     9     cin >> n;
    10     
    11     while(n--) {
    12         cin >> s1;
    13         cin >> s2;
    14         size_t  m = s2.find(s1,0);
    15         int ans = 0;
    16         while(m != string::npos) {
    17             ans++;
    18             m = s2.find(s1,m+1);
    19         }
    20         cout << ans << endl;
    21     }    
    22     
    23     return 0;
    24 }
  • 相关阅读:
    MySQL 5.6.9 RC 发布
    红薯 Java 8 的日期时间新用法
    Couchbase Server 2.0 发布,NoSQL 数据库
    Firefox OS 模拟器 1.0 发布
    Calculate Linux 13 Beta 1 发布
    敏捷测试的团队构成
    Node.js 0.8.16 发布(稳定版)
    JASocket 1.1.0 发布
    Samba 4.0 正式版发布,支持活动目录
    Seafile 1.3 发布,文件同步和协作平台
  • 原文地址:https://www.cnblogs.com/jasonJie/p/6084501.html
Copyright © 2011-2022 走看看