• 微软面试题 之 "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;
    }
  • 相关阅读:
    十四、linux内核裁剪
    十一、进程上下文
    五、进程间通信无名管道
    七、进程间通信信号
    react 中 CSS Modules 的简单使用(解决组件样式覆盖问题)
    react长列表性能优化 reactvirtualized
    vue+echarts绘制相应中国地图和省份地图
    vuex组件 vuexpersistedstate
    vue2 iview switch 使用render渲染,beforechange阻断前传参数
    Linux之crontab e定时任务
  • 原文地址:https://www.cnblogs.com/kevinwan/p/371704.html
Copyright © 2020-2023  润新知