zoukankan      html  css  js  c++  java
  • 微软面试题 之 "Longest Common Sequence"

    求两个string的最长公共子序列

    如:
    "abcdef", "aabacfe" => "abce"
    "swew", "wews" => "wew"

    code:
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    #include <time.h>

    enum { MAX_LEN = 100 };

    void LCS_Aux(const char* s1, int l1, const char* s2, int l2, char* output, int& lo)
    {
        if (l1 <= 0 || l2 <= 0 || l1 > MAX_LEN || l2 > MAX_LEN)
        {
            lo = 0;
        }
        else if (s1[l1-1] == s2[l2-1])
        {
            LCS_Aux(s1, l1-1, s2, l2-1, output, lo);
            output[lo] = s1[l1-1];
            lo++;
        }
        else
        {
            int len1, len2;
            char tmp[MAX_LEN] = {0};
            LCS_Aux(s1, l1-1, s2, l2, output, len1);
            LCS_Aux(s1, l1, s2, l2-1, tmp, len2);
            if (len1 < len2)
            {
                strncpy(output, tmp, len2);
                lo = len2;
            }
            else
            {
                lo = len1;
            }
        }
    }

    char* LCS_Recursive(const char* s1, const char* s2)
    {
        if (s1 == 0 || s2 == 0)
            return 0;

        int len1 = strlen(s1);
        int len2 = strlen(s2);
        char* output = new char[len1];
        memset(output, 0, len1);
        int olen = 0;
        LCS_Aux(s1, len1, s2, len2, output, olen);
        return output;
    }

    int max(int a, int b)
    {
        return a > b ? a : b;
    }

    char* LCS_DP(const char* s1, const char* s2)
    {
        if (s1 == 0 || s2 == 0)
            return 0;

        int l1 = strlen(s1);
        int l2 = strlen(s2);
        if (l1 > MAX_LEN || l2 > MAX_LEN)
            return 0;

        int m[MAX_LEN][MAX_LEN] = {0};
        char d[MAX_LEN][MAX_LEN] = {0};

        for (int i = 0; i < l1; ++i)
        {
            for (int j = 0; j < l2; ++j)
            {
                if (s1[i] == s2[j])
                {
                    if (i == 0 || j == 0)
                    {
                        d[i][j] = '\\';
                        m[i][j] = 1;
                    }
                    else
                    {
                        d[i][j] = '\\';
                        m[i][j] = m[i-1][j-1] + 1;
                    }
                }
                else
                {
                    if (i == 0)
                    {
                        d[i][j] = '-';
                        m[i][j] = m[i][j-1];
                    }
                    else if (j == 0)
                    {
                        d[i][j] = '|';
                        m[i][j] = m[i-1][j];
                    }
                    else
                    {
                        if (m[i][j-1] > m[i-1][j])
                        {
                            d[i][j] = '-';
                            m[i][j] = m[i][j-1];
                        }
                        else
                        {
                            d[i][j] = '|';
                            m[i][j] = m[i-1][j];
                        }
                    }
                }
            }
        }

        // Print the matrix
        for (int i = 0; i < l1; ++i)
        {
            for (int j = 0; j < l2; ++j)
            {
                printf("%d ", m[i][j]);
            }
            printf("\n");
        }

        // Print the path
        for (int i = 0; i < l1; ++i)
        {
            for (int j = 0; j < l2; ++j)
            {
                printf("%c ", d[i][j]);
            }
            printf("\n");
        }

        int len = m[l1-1][l2-1];
        char* result = new char[len+1];
        memset(result, 0, l1);
        char* p = result + len;
        --l1, --l2;
        *p = 0;
        while (l1 >= 0 && l2 >= 0)
        {
            if (d[l1][l2] == '\\')
            {
                *--p = s1[l1];
                --l1, --l2;
            }
            else if (d[l1][l2] == '-')
            {
                --l2;
            }
            else if (d[l1][l2] == '|')
            {
                --l1;
            }
        }
        return result;
    }

    int main(int argc, char* argv[])
    {
        char* input[2][16] =
        {
            { "abcdef", "aabacfe", "abce" },
            { "swew", "wews", "wew" },
        };

        for (int i = 0; i < 2; ++i)
        {
            time_t start = time(0);
            char* result = LCS_Recursive(input[i][0], input[i][1]);
            printf("%s\n", result);
            assert(strcmp(result, input[i][2]) == 0);
            delete[] result;
            printf("%u\n\n", time(0)-start);

            start = time(0);
            result = LCS_DP(input[i][0], input[i][1]);
            printf("%s\n", result);
            assert(strcmp(result, input[i][2]) == 0);
            delete[] result;
            printf("%u\n\n", time(0)-start);
        }
        return 0;
    }
  • 相关阅读:
    正在找工作/打算找工作的看过来!
    xx星空面试题
    买的书不少,看的书不多,这是病
    公司那么多 我想去面面
    Android设备直接运行java项目?还杀不死?
    node-sass安装失败 解决办法(linux和window)
    Vue + element控制鼠标右键菜单
    Vue.js中Promise、异步、同步、定时器
    选择器&伪类选择器
    根据城市名称获取对应的省份名称
  • 原文地址:https://www.cnblogs.com/kevinwan/p/371704.html
Copyright © 2011-2022 走看看