编辑距离矩阵

时间:2016-11-04 00:41:24

标签: c algorithm edit-distance

我正在尝试构建一个程序,该程序需要两个字符串并填充编辑距离矩阵。绊倒我的是,对于第二个字符串输入,它正在跳过第二个输入。我尝试用getch()清除缓冲区,但它没有用。我也尝试过切换到scanf(),但这也导致了一些崩溃。求救!

代码:

#include <stdio.h>
#include <stdlib.h>

int min(int a, int b, int c){
    if(a > b && a > c)
        return a;
    else if(b > a && b > c)
        return b;
    else
        return c;
}

int main(){

    // allocate size for strings
    int i, j;
    char *input1 = (char*)malloc(sizeof(char)*100);
    char *input2 = (char*)malloc(sizeof(char)*100);

    // ask for input
    printf("Enter the first string: ");
    fgets(input1, sizeof(input1), stdin);
    printf("\nEnter the second string: ");
    fgets(input2, sizeof(input2), stdin);

    // make matrix
    int len1 = sizeof(input1), len2 = sizeof(input2);
    int c[len1 + 1][len2 + 1];

    // set up input 2 length
    for(i = 0; i < len2 + 1; i++){
        c[0][i] = i;
    }

    // set up input 1 length
    for(i = 0; i < len1 + 1; i++){
        c[i][0] = i;
    }

    // fill in the rest of the matrix
    for(i = 1; i < len1; i++){
        for(j = 1; j < len2; j++){
            if(input1[i] == input2[j]) // if the first letters are equal make the diagonal equal to the last
                c[i][j] = c[i - 1][j - 1];
            else
                c[i][j] = 1 + min(c[i - 1][j - 1], c[i - 1][j], c[i][j - 1]);
        }
    }

    // print the matrix
    printf("\n");
    for(j = 0; j < len2; j++){
        for(i = 0; i < len1; i++){
            printf("|  %d", c[i][j]);
        }
        printf("\n");
    }

    return 1;
}

1 个答案:

答案 0 :(得分:1)

坚持fgets

正如其他人所指出的那样,使用char input1[100]代替char *input1 = malloc(...)

但是,即使进行了更改,这会使sizeof内的fgets更正,在设置sizeoflen1时使用len2也是错误的。您将处理100的整个缓冲区,即使它们只有10个有效字符(即其余的未定义/随机)。

你[可能]想要的是strlen [和换行符]以获得实际有用的长度。

这里有修改后的代码[请原谅无偿风格的清理]:

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

int
min(int a, int b, int c)
{
    if (a > b && a > c)
        return a;
    if (b > a && b > c)
        return b;
    return c;
}

int
main(void)
{

    // allocate size for strings
    int i;
    int j;
    char input1[100];
    char input2[100];

    // ask for input
    printf("Enter the first string: ");
    fgets(input1, sizeof(input1), stdin);
    int len1 = strlen(input1);
    if (input1[len1 - 1] == '\n') {
        input1[len1 - 1] = 0;
        --len1;
    }

    printf("\nEnter the second string: ");
    fgets(input2, sizeof(input2), stdin);
    int len2 = strlen(input2);
    if (input2[len2 - 1] == '\n') {
        input2[len2 - 1] = 0;
        --len2;
    }

    // make matrix
    int c[len1 + 1][len2 + 1];

    // set up input 2 length
    for (i = 0; i < len2 + 1; i++) {
        c[0][i] = i;
    }

    // set up input 1 length
    for (i = 0; i < len1 + 1; i++) {
        c[i][0] = i;
    }

    // fill in the rest of the matrix
    for (i = 1; i < len1; i++) {
        for (j = 1; j < len2; j++) {
            // if the 1st letters are equal make the diagonal equal to the last
            if (input1[i] == input2[j])
                c[i][j] = c[i - 1][j - 1];
            else
                c[i][j] = 1 + min(c[i - 1][j - 1], c[i - 1][j], c[i][j - 1]);
        }
    }

    // print the matrix
    printf("\n");
    for (j = 0; j < len2; j++) {
        for (i = 0; i < len1; i++) {
            printf("|  %d", c[i][j]);
        }
        printf("\n");
    }

    return 1;
}

<强>更新

  

好的,我明白你的意思!我试图使用malloc的原因是为了避免制作矩阵,我必须打印100x100空格的大小。

使用固定大小input1malloc ed fgetsabcdef\n只会将其填充到输入的输入大小[必要时剪裁到第二个参数]。但是,任何填充缓冲区的剩余部分(例如右边的空格)。 所做的是在从输入读取的最后一个char [通常是换行符]之后添加一个EOS [字符串结束]字符[这是一个二进制0x00]。

因此,如果输入字符串为:strlen,则[可从input1[8]获得]的长度为7,输入[7]将为0x00,input1[99]至{{1}将有未定义/随机/不可预测的值和空格。

由于换行符char非常有用,因此在进一步处理之前通常会将其删除。例如,在计算小词组的编辑距离时,它并不是非常相关。

  

使用strlen()只计算数组中的字符数,还是包括所有空格?

正如我上面提到的,fgets 它会做你想要/期望的事情。

strlen仅将字符计数到[但,包括EOS终结符字符(即)为零]。如果这些字符中的某些字符碰巧是空格,那么计算为strlen - 这就是我们想要的。

考虑计算以下任意两个词组之间的编辑距离:

quick brown fox jumped over the lazy dogs
the quick brown fox jumped over lazy dogs
quick brown fox jumps over the lazy dog

在每种情况下,我们希望 strlen在长度计算中包含[internal / embedded]空格。这是因为 完全有效,无法计算短语的编辑距离。

malloc有一个有效用法:当数据量太大而无法放入堆栈时。大多数系统都有默认限制(例如,在linux下,它是8 MB)。

假设我们计算了两本书章节的编辑距离[从文件中读取],我们有(例如):

char input1[50000];
char input2[50000];

上述情况适合,但c矩阵会导致堆栈溢出:

int c[50000][50000];

因为它的大小为50000 * 50000 * 4,大约为9.3 GB。

因此,为了适应所有这些数据,我们需要在堆上分配它。虽然malloc 可以c维持2D矩阵访问,但我们必须创建一个函数并将指针传递给{{ 1}}到它。

所以,这是一个修改版本,可以输入任意大的尺寸:

c