HOJ 12811 单词对比(很巧的处理方法,运用26个字母的个数)

Jumble Match
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB
Total submit users: 14, Accepted users: 13
Problem 12881 : No special judgement
Problem description

For the purpose of this problem, a word matches a pattern if a substring of the word matches the pattern. A pattern can contain letters (which should be matched explicitly) and underscores (which match any single letter). Finally, a pattern is considered matched if any jumble (permutation) of the pattern characters matches.
For example, the pattern cat matches words such as cat, scat, and cater because cat is a substring of the word. However, the pattern also matches words that contain permutations of cat as a substring, such as tacit, latch, and fact. And the pattern cat_ would match any word that contains a 4-character substring that is some permutation of the letters c, a, t, and any other letter, which would therefor match words such as track, cant, or crate.
Your task is to write a program that searches for a jumble match in a set of input words.


Input

Input will consist of specifications for a series of tests. Information for each test begins with a line containing a single string of length 1 <= n < 100 that specifies the pattern to search for. A pattern string consisting of a single dot terminates the input.
The lines following the pattern begin with an integer 1 <= n <= 10 that specifies the number of words on the line, followed by the words themselves, with a single space between items. Words are strings of alphabetic characters of length 1 < n < 20. A line with a word count of 0 ends the input for each test.


Output

Output should consist of one line for each test comprising the test number (formatted as shown) followed by a single space and the number of words in the input set that match the pattern.


Sample Input
cat
10 act canto chest colt crest eject hutch scant tact track
10 bitch cat civet cotta cut evict notch stack tic tuck
2 cant chert
0
cat_
10 act canto chest colt crest eject hutch scant tact track
10 bitch cat civet cotta cut evict notch stack tic tuck
2 cant chert
0
Australian Programming Contest! 2013
c_t_
10 act canto chest colt crest eject hutch scant tact track
10 bitch cat civet cotta cut evict notch stack tic tuck
2 cant chert
0
.
Sample Output
Test 1: 4
Test 2: 6
Test 3: 14
Problem Source
AUPC 2013


题目意思:给你一种定义,一个串S和一个单词Word,如果满足定义则说明匹配了,给很多单词,问有多少个和串S匹配的。定义为这样的,如果word里面包含任一一种串S的排列,则匹配,另外,串S里面包含'_',可以和任意字母相同。       然后串S的长度为小于100,单词word的长度小于20。最多200个单词。

分析:这题想想就是个很简单的字符串模拟,至于怎么做的更简单去处理匹配且在'_'的情况下,这是个问题。

    如果串S大于20。不用说了,一个匹配的单词都没有。对于串S,开一个26大小的数组,记录a~~z的个数。然后对于word,开二维数组[len][26],大小是单词长度和同样记录第i个位置之前的a~~z的个数。那么就是对在word里暴力长度为S。字串去匹配,只要大于等于串S的左右字母个数就ok了。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define rt return
#define sf scanf
#define pf printf
#define si(n) sf("%d",&n)
#define pi(n) pf("%d",n)
#define REP0(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define REP(i,s,n) for(int i=s;i<=(n);i++)
#define db double
#define pb push_back
#define LL long long
#define INF 0x3fffffff
#define eps 1e-8
#define PI acos(-1)
#define maxn
using namespace std;
int tar[26];
int arr[21][26];
void init(char *s){
    memset(tar,0,sizeof(tar));
    int i=0;
    while(s[i]){
        if(s[i]=='_'){i++;continue;}
        int x=s[i]-'a';
        tar[x]++;
        i++;
    }
}
bool ok(char *s,char *word){
    int ls=strlen(s);
    int lw=strlen(word);
    if(ls>lw)rt false;
    memset(arr[0],0,sizeof(arr[0]));
    for(int i=0;i<lw;i++){
        int x=word[i]-'a';
        for(int j=0;j<26;j++)arr[i+1][j]=arr[i][j];
        arr[i+1][x]++;
    }
    for(int i=0,j;i<=(lw-ls);i++){
        for(j=0;j<26;j++){
            if(arr[i+ls][j]-arr[i][j]>=tar[j] )//zhi qian suo you
                continue;
            else break;
        }
        if(j==26)rt true;
    }
    rt false;
}
int main(){
    #ifdef ACBang
    freopen("in.txt","r",stdin);
    #endif
    char s[110];
    int CAS=1;
    while(sf("%s",s),s[0]!='.'){
        init(s);
        int n,tot=0;
        while(sf("%d",&n),n!=0){
            while(n--){
                char word[21];
                sf("%s",word);
                if(ok(s,word)==true){
//                    cout<<word<<endl;
                    tot++;
                }
            }
        }
        pf("Test %d: %d\n",CAS++,tot);
    }
    rt 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值