为非常大的输入编辑距离动态编程

时间:2014-10-07 20:00:28

标签: c++ arrays dynamic-programming edit-distance

我正在解决众所周知的编辑距离动态编程问题。实际上问题是给出了两个字符串string1和string2,并给出了删除,插入和替换字符的成本,我必须以最低成本将string1转换为string2。对于DP,我必须使用二维数组。对于一个小字符串(大小<= 10000)我的代码正在工作但是对于更大的输入(大小> = 100000),编译器说&#34;数组大小太大&#34 ;。如果问题必须使用动态编程解决(输入大小= 100000),那么请告诉我应该如何处理这个错误。这是我的代码。

#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <queue>
#include <iomanip>
#include <string>
#include <math.h>
#include <limits>
#include <map>
#include <float.h>
#include <limits.h>
#include <string.h>
using namespace std;
#define rep(i,a,N) for(int i=a;i<N;++i)
int DP[10000][10000],delete_cost,add_cost,replace_cost;
string first,second;
int Min(int x,int y,int z){
    int min=x<y?x:y;
    min=min<z?min:z;
    return min;
}

int Transform(int i,int j){ 
    if(DP[i][j]!=-1){
        //printf("DP is set\n");
        return DP[i][j];
    }
    if(i==first.size())
        return (second.size()-j)*add_cost;
    if(j==second.size())
        return (first.size()-i)*delete_cost;
    if(first.at(i)!=second.at(j)){
        int add,del,rep;
        add=Transform(i,j+1)+add_cost;
        del=Transform(i+1,j)+delete_cost;
        rep=Transform(i+1,j+1)+replace_cost;
        return DP[i][j]=Min(add,del,rep);
    }
    else
        return DP[i][j]=Transform(i+1,j+1);

}
    int main(){
    int T,a,b,k,ans;
    scanf("%d",&T);

    while(T--){
        memset(DP,-1,sizeof(DP));
        cin>>first;
        cin>>second;
        scanf("%d %d %d",&a,&b,&k);
        add_cost=a;
        delete_cost=b;
        replace_cost=k;
        //ans=Transform(0,0);
        //if(ans<=k)
            printf("%d\n",ans );
        //else
        //  printf("%d\n",-1);
    }
return 0;
}

1 个答案:

答案 0 :(得分:0)

是的,因为你的100000 * 100000 32位整数数组占用了40千兆字节的内存。 您需要使用不同的算法。如果您只需要将编辑距离计算到某个最大值k,那么经典算法的修改版本仅使用O(n * (2k + 1))存储(其中n是字符串长度)因为它只使用动态编程矩阵的中间2k + 1对角线。