zoukankan      html  css  js  c++  java
  • hdu 2087 剪花布条

    一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?

    Input输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
    Output输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
    Sample Input
    abcde a3
    aaaaaa  aa
    #
    Sample Output
    0
    3

    kmp匹配单个字符串。
    kmp的大概意思是,对于对照串(匹配对照用),Next记录到第i各字符时最大前缀后缀匹配个数,然后在对主串找和对照串匹配的子串时,如果到某个字符位置j发现不相同,并不需要从开头的下一个字符开始匹配,因为Next[j]记录了最大前缀后缀匹配数,此次是从前缀开始匹配的,下一次只需要从后缀开始就好了,模板串前移j - Next[j]位,
    举个例子主串s,对照串p,s = "abcdabe",p = "abcdabc",从头开始匹配,发现匹配到第6位时(下标从0开始),'e' != 'c',此时s还在第五位,p也是,此时不需要从s的第1位开始匹配p串,而是从第4位开始,而且第4、5位匹配过了,p串只需要从第2位开始就好了,因为此时最大前缀后缀匹配数为2,也确实是这样。这就是Next数组的作用。
    c代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void findnext(char *str,int *Next) {///找最大前缀后缀匹配数
        int i = 0,j = -1,len = strlen(str);
        Next[0] = -1;///初始为-1
        while(i < len) {
            if(j == -1 || str[i] == str[j]) {
                Next[++ i] = ++ j;
            }
            else j = Next[j];
        }
    }
    int kmp(char *s,char *p) {
        int Next[1000],ans = 0;
        int slen = strlen(s),plen = strlen(p);
        findnext(p,Next);
        int i = -1,j = -1;
        while(i < slen) {
            if(j == -1 || s[i] == p[j]) {
                i ++,j ++;
                if(j == plen) {
                    ans ++;
                    j = 0;///j归0 从头开始匹配
                }
            }
            else j = Next[j];
        }
        return ans;
    }
    int main() {
        char s[1000],p[1000];
        while(~scanf("%s",s)&&strcmp(s,"#")) {
            scanf("%s",p);
            printf("%d
    ",kmp(s,p));
        }
    }

    用c++ string类写了一下,不用像kmp考虑那么累

    c++代码:

    #include <iostream>
    #include <string>
    
    using namespace std;
    int check(string a,string b) {
        int d = b.size(),ans = 0;
        int size = a.size() - d + 1;
        string t;
        for(int i = 0;i <= size;i ++) {
            if(a[i] == b[0]) {
                t.assign(a,i,d);
                if(t == b) {
                    ans ++;
                    i += d - 1;
                }
            }
        }
        return ans;
    }
    int main() {
        string a,b;
        while(cin>>a&&a!="#") {
            cin>>b;
            cout<<check(a,b)<<endl;
        }
    }
  • 相关阅读:
    git 实践(二) push的使用
    git 实践(一) pull的使用
    redux项目实战应用笔录
    浅谈ES6的Object.assign()浅拷贝
    React下reducer中处理数组&&对象的赋值改动
    git pull与git clone
    (0)网络编程基础(网络基本知识)
    (1)什么是socket(套接字)
    (12)异常处理
    (11)类的内置函数
  • 原文地址:https://www.cnblogs.com/8023spz/p/7764305.html
Copyright © 2011-2022 走看看