编程之美----相似字符串匹配(解答记录)

来源:互联网 发布:python 召回率和准确率 编辑:程序博客网 时间:2024/04/28 20:30

题目描述:

对于两个长度相等的字符串,我们定义其距离为对应位置不同的字符数量,同时我们认为距离越近的字符串越相似。例如,“0123”和“0000”的距离为 3,“0123”和“0213”的距离则为 2,所以与“0000”相比,“0213”和“0123”最相似。

现在给定两个字符串 S1 和 S2,其中 S2 的长度不大于 S1。请在 S1 中寻找一个与 S2 长度相同的子串,使得距离最小。

输入

输入包括多组数据。第一行是整数 T,表示有多少组测试数据。每组测试数据恰好占两行,第一行为字符串 S1,第二行为 S2。所有字符串都只包括“0”到“9”的字符。

输出

对于每组测试数据,单独输出一行“Case #c: d”。其中,c 表示测试数据的编号(从 1 开始),d 表示找到的子串的最小距离。

数据范围

1 ≤ T ≤ 100

小数据:字符串长度不超过 1000

大数据:字符串长度不超过 50000

样例输入

3
0123456789
321
010203040506070809
404
20121221
211

样例输出

Case #1: 2
Case #2: 1
Case #3: 1

解题思路:
参考的是

现在假设 s1="010203040506070809",s2="404",首先对 s1 进行预处理,标记出每个字符出现的索引,得到下面的表格:

字符出现的索引'0'0,2,4,6,8,10,12,14,16'1'1'2'3'3'5'4'7'5'9'6'11'7'13'8'15'9'17

然后在读取 s2 的每个字符时,根据表格在一个长为 n 的 int 数组 ans 上进行标记 s2[0] 出现的位置。例如现在 s2[0] = '4',表格中字符 '4' 对应的索引只有 7,那么令 ans[7-0]++;然后读取 s2[1]='0',表格中字符 '0' 对应的索引有 0,2,4,6,8,10,12,14 和 16,那么就令 ans[0-1]、ans[2-1]、ans[4-1]、ans[6-1]、ans[8-1]、ans[10-1]、ans[12-1]、ans[14-1] 和 ans[16-1] 均加一;最后读取 s2[2] = '4',令 ans[7-2]++。最后得到的 ans 数组如下所示:

ans = {0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 1, 0 ,1, 0, 1};

那么这个 ans 表示什么呢?ans[i] 表示 s1ii+n 与 s20n 中完全相同的字符的个数,最后只要统计 ans 中最大的那个,就表示距离最小。

为什么是ans[2-1],ans[4-1],ans[6-1]......这里面的i为什么要减去?个人的理解是:在S1i.......i+n中后J-i的字串中能够匹配当前字符。

下面是自己编译通过的代码:(样例数据已经通过)
#include<iostream>#include<string>using namespace std;int num[10][60000],ans[60000];int main(){    int T,k,len1,len2,anss;string s1,s2;    int t=1;    cin>>T;    while(T>=t)    {        ++t;        cin>>s1;cin>>s2;        len1=s1.length();len2=s2.length();        for(int i=0;i<10;++i) num[i][0]=0;        //        for(int i=0;i<len1;++i)        {            k=s1[i]-'0';            ++num[k][0];//sum of char// k便于以后使用            num[k][num[k][0]]=i;            ans[i]=0;        }        for(int i=0;i<len2;++i)        {            k=s2[i]-'0';            for(int j=1;j<=num[k][0];++j)            {                if(num[k][j]-i>=0) ans[num[k][j]-i]++;            }        }        anss=0;        for(int i=0;i<len1-len2+1;++i)        {            if(ans[i]>anss) anss=ans[i];        }        anss=len2-anss;//anss record the similar // anss记录的是相同字符有多少个        cout<<"case #"<<t-1<<": "<<anss<<endl;    }    return 0;}




0 0