Codeforces-144C-Anagram Search(思維)

C. Anagram Search
time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

A string t is called an anagram of the string s, if it is possible to rearrange letters in t so that it is identical to the string s. For example, the string "aab" is an anagram of the string "aba" and the string "aaa" is not.

The string t is called a substring of the string s if it can be read starting from some position in the string s. For example, the string "aba" has six substrings: "a", "b", "a", "ab", "ba", "aba".

You are given a string s, consisting of lowercase Latin letters and characters "?". You are also given a string p, consisting of lowercase Latin letters only. Let's assume that a string is good if you can obtain an anagram of the string p from it, replacing the "?" characters by Latin letters. Each "?" can be replaced by exactly one character of the Latin alphabet. For example, if the string p = «aba», then the string "a??" is good, and the string «?bc» is not.

Your task is to find the number of good substrings of the string s (identical substrings must be counted in the answer several times).

Input

The first line is non-empty string s, consisting of no more than 105 lowercase Latin letters and characters "?". The second line is non-empty string p, consisting of no more than 105 lowercase Latin letters. Please note that the length of the string p can exceed the length of the string s.

Output

Print the single number representing the number of good substrings of string s.

Two substrings are considered different in their positions of occurrence are different. Thus, if some string occurs several times, then it should be counted the same number of times.

Examples
Input
bb??x???
aab
Output
2
Input
ab?c
acb
Output
2
Note

Consider the first sample test. Here the string s has two good substrings: "b??" (after we replace the question marks we get "baa"), "???" (after we replace the question marks we get "baa").

Let's consider the second sample test. Here the string s has two good substrings: "ab?" ("?" can be replaced by "c"), "b?c" ("?" can be replaced by "a").

思路:首先確定肯定輸出爲0的情況,當p串長度大於s串時或者p爲空串時輸出0;然後從s串的下標len2開始,每次維護它前len2個字符出現的次數(前綴和思想),然後判斷的時候某一段字串‘?’的個數等於字串相對於p串缺少的字符個數,則ans++,如果子串中某個字符出現的次數大於p串中該字符出現的次數,是不符合要求的;具體請看代碼。

AC代碼:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
    int cnt[27];
}arr[100005];//前綴數組,?放在第26個
int cnt[26];//記錄p串中各個字符出現的次數
char str1[100005],str2[1000006];
int main()
{
    while(~scanf("%s%s",str1+1,str2+1))
    {
        int len1=strlen(str1+1);
        int len2=strlen(str2+1);
        if(len2>len1||len2==0){//肯定爲0的情況
            printf("0\n");
            continue;
        }
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<=len1;i++)
            memset(arr[i].cnt,0,sizeof(arr[i].cnt));
        for(int i=1;i<=len2;i++)
            cnt[str2[i]-'a']++;
        int ans=0;
        for(int i=1;i<=len2;i++)//先處理出第一項
        {
            if(str1[i]=='?') arr[len2].cnt[26]++;
            else arr[len2].cnt[str1[i]-'a']++;
        }
        for(int i=len2+1;i<=len1;i++)
        {
            for(int j=0;j<=26;j++)//先繼承上一個的
                arr[i].cnt[j]=arr[i-1].cnt[j];
            if(str1[i-len2]=='?') arr[i].cnt[26]--;//刪掉最左邊的
            else arr[i].cnt[str1[i-len2]-'a']--;
            if(str1[i]=='?') arr[i].cnt[26]++;//加上當前的
            else arr[i].cnt[str1[i]-'a']++;
        }
        for(int i=len2;i<=len1;i++)
        {
            int c=0,flag=1;;
            for(int j=0;j<=25;j++)
            {
                if(cnt[j]){
                    if(arr[i].cnt[j]<=cnt[j])
                        c+=(cnt[j]-arr[i].cnt[j]);
                    else{
                        flag=0;
                        break;
                    }
                }
            }
            if(flag&&arr[i].cnt[26]==c) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章