HD3795 Diff【文本处理】

Diff
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 600144/600144 K (Java/Others)
Total Submission(s): 318 Accepted Submission(s): 38

Problem Description
In computing, diff is a file comparison utility that outputs the differences between two files. It is typically used to show the changes between a file and a former version of the same file. Diff displays the changes made per line for text files.
The operation of diff is based on solving the longest common subsequence problem which is as follows: Given two sequences A = a1, a2, …, aM, and B = b1, b2, …, bN, find the length, k, of the longest sequence C = c1, c2, …, ck such that C is a subsequence of both A and B. As an example, if
A = d, y, n, a, m, i, c and B = p, r, o, g, r, a, m, m, i, n, g
then the longest common subsequence is a, m, i( {3,4,5} from A, {5,6,8} from B) and has length 3.
You may find {5,7,8} from B is also a, m, i, but {5,6,8} is lexicographic smaller, so we choose the former one. We always choose the lexicographic smallest one.
From the longest common subsequence it’s only a small step to get diff-like output:
dyn-progr+m+c-ng+
where ‘-’ means a deletion from and ‘+’ means an addition to the first string.
Now you are supposed to simulate the diff operation.

Input
Your program must read test cases from standard input.
The input file consists of several test cases. Each case contains the contents of two files. The case starts with two non-negative integers N and M (both <= 50), then followed by N+M lines, each contains a string of no more than 80 characters. The first N lines are the contents of the first file, while the second M lines are of the second file.
The input is finished by a negative N.

Output
For each test case, your program must output to standard output. If there is no difference found between the two files, print in a line “No difference found”. If there is nothing in common between the two files, print in a line “Totally different”. Otherwise, first print in a line the length of the longest sequence. Then for each line of the first file, print the line number, and output the differences in the diff-like format line by line, as shown by the sample output.

Sample Input
1 1
This is a test
This is a test
1 1
ab
cd
1 1
dynamic
programming
4 4
This is a test
which is more complicated
zzz
than …
This is another test
of the project
which is much more complex
than the previous one
-100

Sample Output
No difference found
Totally different
3
line #1
dyn-progr+m+c-ng+
39
line #1
nother+
line #2
of the project+
uch m+icat-d-
line #3
zzz-
line #4
x+
…-the previous one+

Source
浙大计算机研究生保研复试上机考试-2011年

问题链接HD3795 Diff
问题简述:(略)
问题分析:解题程序来自网络,CV来的,不是原创,不解释。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* HD3795 Diff */

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

#define N 5010

int n, m, l1, l2, nt, na, line, dp[N][N], flg[N][N], f[2][N], ned[2], usd[2];
char s[100], ss[2][N], common[N], ans[2 * N], mark[3] = "-+";

void LCS(char *a, char *b) {
    int i, j;
    for(i = 0; i <= l1; ++i) dp[i][0] = 0;
    for(i = 0; i <= l2; ++i) dp[0][i] = 0;
    for(i = 1; i <= l1; ++i)
        for(j = 1; j <= l2; ++j)
            if(a[i - 1] == b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                flg[i][j] = 1;
            }
            else {
                if(dp[i - 1][j] > dp[i][j - 1]) {
                    dp[i][j] = dp[i - 1][j];
                    flg[i][j] = 2;
                }
                else {
                    dp[i][j] = dp[i][j - 1];
                    flg[i][j] = 3;
                }
            }
            return;
}

void traceback(int i, int j) {
    while(i > 0 && j > 0) {
        if(flg[i][j] == 1) {
            common[nt++] = ss[0][i - 1];
            --i; --j;
        }
        else if(flg[i][j] == 2) --i;
        else
            --j;
    }
}

void addmk(int i) {
    if(na != 0 && ans[na - 1] != '+' && ans[na - 1] != '-')
        ans[na++] = mark[i];
}

void addline(int i) {
    if(na != 0 && ans[na - 1] != '\n') {
        addmk(i);
        printf("%s\n", ans);
        if(!i) printf("line #%d\n", line++);
        na = 0; memset(ans, 0x00, sizeof(ans));
    }
}

void checked(int i, int idx) {
    if(ned[i] > usd[i] && idx == f[i][usd[i]]) {
        usd[i]++;
        addline(i);
    }
}

void out(int i, int &idx, char ed) {
    if(ss[i][idx] == ed) {
        ++idx;
        checked(i, idx);
        return;
    }
    while(ss[i][idx] != ed) {
        ans[na++] = ss[i][idx];
        ++idx;
        checked(i, idx);
    }
    ++idx;
    addmk(i);
    checked(i, idx);
    return;
}

int main() {
    int i, j;
    while(scanf("%d", &n), n >= 0) {
        scanf("%d", &m);
        getchar();
        memset(f, 0, sizeof(f));
        memset(ss, 0x00, sizeof(ss));
        memset(ans, 0x00, sizeof(ans));
        memset(common, 0x00, sizeof(common));
        ned[0] = ned[1] = 0;
        for(i = 0; i < n; ++i) {
            gets(s);
            strcat(ss[0], s);
            if(i < n - 1)f[0][ned[0]++] = strlen(ss[0]);
        }
        for(i = 0; i < m; ++i) {
            gets(s);
            strcat(ss[1], s);
            if(i < m - 1)f[1][ned[1]++] = strlen(ss[1]);
        }
        if(!strcmp(ss[0], ss[1])) {
            puts("No difference found");
            continue;
        }
        l1 = strlen(ss[0]); l2 = strlen(ss[1]);
        LCS(ss[0], ss[1]);
        if(!dp[l1][l2]) {
            puts("Totally different");
            continue;
        }
        nt = na = 0;
        memset(ans, 0x00, sizeof(ans));
        printf("%d\n", dp[l1][l2]);
        traceback(l1, l2);
        i = 0, j = 0; line = 2;
        usd[0] = usd[1] = 0;
        printf ("line #1\n");
        while(nt > 0) {
            char ch = common[nt - 1];
            nt--;
            out(0, i, ch);
            out(1, j, ch);
        }
        out(0, i, 0);
        out(1, j, 0);
        printf("%s\n", ans);
    }

    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值