编辑距离

c++

编辑距离

/*
    问题描述:
        给定 n 个长度不超过 10 的字符串以及 m 次询问,每次询问给出一个字符串和一个操作次数上限。
        对于每次询问,请你求出给定的 n 个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。
        每个对字符串进行的单个字符的插入、删除或替换算作一次操作。

    输入格式:
        第一行包含两个整数 n 和 m。
        接下来 n 行,每行包含一个字符串,表示给定的字符串。
        再接下来 m 行,每行包含一个字符串和一个整数,表示一次询问。
        字符串中只包含小写字母,且长度均不超过 10。

    输出格式
        输出共 m 行,每行输出一个整数作为结果,表示一次询问中满足条件的字符串个数。

    数据范围
        1 ≤ n, m ≤ 1000,

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const int N = 1010, M = 12;
int n, m;
char s[N][M];
int f[M][M];
char t[M];
int cost;


int solution_one() {
    int ret = 0;
    int a, b;
    for (int i = 1; i <= n; i ++ ) {
        memset(f, 0, sizeof f);
        a = strlen(s[i] + 1);
        b = strlen(t + 1);
        for (int j = 0; j <= a; j ++ ) {
            f[j][0] = j;
        }
        for (int j = 0; j <= b; j ++ ) {
            f[0][j] = j;
        }

        for (int j = 1; j <= a; j ++ ) {
            for (int k = 1; k <= b; k ++ ) {
                if (s[i][j] == t[k]) {
                    f[j][k] = f[j - 1][k - 1];
                } else {
                    f[j][k] = min(
                        min(
                            f[j - 1][k] + 1,
                            f[j][k - 1] + 1
                        ),
                        f[j - 1][k - 1] + 1
                    );
                }
            }
        }

        if (f[a][b] <= cost) {
            ret += 1;
        }
    }
    return ret;
}


int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) {
        scanf("%s", s[i] + 1);
    }

    int res;
    while (m -- ) {
        scanf("%s%d", t + 1, &cost);
        res = solution_one();
        printf("%d\n", res);
    }

    return 0;
}

posted @ 2022-07-05 19:39  lucky_light  阅读(51)  评论(0编辑  收藏  举报