(map)后缀字符串

一天蒜头君得到 n 个字符串 si?,每个字符串的长度都不超过 10。
蒜头君在想,在这 n 个字符串中,以 si 为后缀的字符串有多少个呢?


输入格式
第一行输入一个整数 n。
接下来 n 行,每行输入一个字符串 si。


输出格式
输出 n 个整数,第 i个整数表示以 si为后缀的字符串的个数。


数据范围
对于 50%的数据,1≤n≤10^3。
对于 100%的数据,1≤n≤10^5。
所有的字符串仅由小写字母组成。


输入样例:
3
ba
a
aba


输入样例:
2
3
1

解一,由于50%数据量在10^3,所以尝试暴力破解,但是会超时,可以过50%的数据:

 

#include <string.h>
#include <stdlib.h>
#include <iostream>

using namespace std;
string v[100005];                                     //字符串数组  比vector节省 
int main() {
    int n,num=0;
    string s,a,b;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        cin>>s;
        v[i]=s;
    }
    for(int i=0;i<n;i++){                             //v[i]为作为后缀的字符串 
        num=0;
        a=v[i];
        for(int p=0;p<n;p++){                         //v[p]为长字符串,判断是否以v[i]后缀 
            b=v[p];
            if(a.length()>b.length()){                //v[p]应该为长字符串,如果长度都比v[i]小,则不参与比较 
                continue;
            }
            int ok=1;
            for(int k=0;k<a.length();k++){            //k为后缀的位置 
                if(a[k]!=b[b.length()-a.length()+k]){
                    ok=0;
                    break;        
                }
            }
            num+=ok;
        }
        printf("%d\n",num);
    }
    return 0;
}

 

 

解二:把每个字符串的每个后缀串放入map,再在map中找以每个字符串后缀的结果数(AC代码)

#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <map>
using namespace std;
string v[100000];
int main() {
    map<string,int >mp;
    int n,num=0;
    string s,a,b;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        cin>>s;
        v[i]=s;
        for(int j=0;j<s.length();j++){
            mp[s.substr(j)]++;               //把第i个字符串的j位置以后都作为后缀串放入map 
        }                                    //并且每个字符串不可能提供重复的后缀串,因为每个字符串提供的后缀串随j的循环长度在减小 
    }
    for(int i=0;i<n;i++){
        printf("%d\n",mp[v[i]]);            //直接在map找以每个字符串为后缀串的结果 
    }
    return 0;
}

 

posted @ 2020-03-02 17:38  Maxwell·  阅读(445)  评论(0编辑  收藏  举报