相似字符串(编程之美2013初赛题2)

时间限制: 4000ms 内存限制: 256MB

 

描述

对于两个长度相等的字符串,我们定义其距离为对应位置不同的字符数量,同时我们认为距离越近的字符串越相似。例如,“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
 

 

//source here
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

const int kMAXN = 50010;

char s[kMAXN], t[kMAXN];
int snxt[kMAXN];
int nxt[kMAXN];
int ans[kMAXN];
int slast[10];
int n, m;
void work(int c, int sp) {
  while (sp < m) {
    while (slast[c] < n && slast[c] < sp) slast[c] = snxt[slast[c]];
    for (int i = slast[c]; i < n; i = snxt[i]) {
      int st = i - sp;
      if (st + m > n) break;
      ans[st]++;
    }
    sp = nxt[sp];
  }
}
int main() {
  int T, cp = 0;
  for (scanf("%d", &T); T; T--) {
    scanf("%s%s", s, t);
    n = strlen(s);
    m = strlen(t);

    int last[10];
    for (int i = 0; i < 10; i++) slast[i] = n;
    for (int i = n - 1; i >= 0; i--) {
      int c = s[i] - '0';
      snxt[i] = slast[c];
      slast[c] = i;
    }

    for (int i = 0; i < 10; i++) last[i] = m;
    for (int i = m - 1; i >= 0; i--) {
      int c = t[i] - '0';
      nxt[i] = last[c];
      last[c] = i;
    }

    memset(ans, 0, sizeof ans);
    for (int i = 0; i < 10; i++) work(i, last[i]);
    int max_ans = 0;
    for (int i = 0; i + m <= n; i++)
      if (ans[i] > max_ans) max_ans = ans[i];
    printf("Case #%d: %d\n", ++cp, m - max_ans);
  }
  return 0;
}


#include <string>
#include <iostream>


using namespace std;


int minDistance(const string strA,const string strB){
const char *a=strA.c_str(),*b=strB.c_str();
const int lena=strA.length(),lenb=strB.length();
int rst=50000,count;
for(int i=0;i<=lena-lenb;i++)
{
count=0;
for(int j=0;j<lenb;j++)
{
if(a[i+j]!=b[j])
count++;
if(count>=rst)
break;
}
if(rst>count)
rst=count;
}
return rst;
}


int _tmain(int argc, _TCHAR* argv[])
{
int T;
cin>>T;
getchar();
string strA,strB;
int rst;
for(int i=1;i<=T;i++){
getline(cin,strA);
getline(cin,strB);
rst=minDistance(strA,strB);
cout<<"Case #"<<i<<": "<<rst<<endl;
}
return 0;
}


 


 

posted @ 2013-04-14 00:13  xinyuyuanm  阅读(229)  评论(0编辑  收藏  举报