• 动态规划


      动态规划,以空间换时间,自底向上求解

      计算两字符串的最长公共子序列(可以不连续)

    /**
     找出 两个 字符串 的公共 子序列(动态规划)
     @param str1 字符串1
     @param str2 字符串2
     */
    void maxPublicSubSequence(char *str1, char *str2) {
        assert(str1 != NULL && str2 != NULL);
        
        // 字符串 1 长度
        int str1Length = strlen(str1);
        // 字符串 2 长度
        int str2Length = strlen(str2);
        // 开辟 二维 存储 数组 (并初始化 值为:0)
        
        int **postionArray = (int **)malloc(sizeof(int *) * (str1Length + 1));
        
        for (int i = 0; i <= str1Length; i ++) {
            postionArray[i] = (int *)malloc(sizeof(int) * (str2Length + 1));
        }
        
        for (int i = 0; i <= str1Length; i++) {
            for (int j = 0; j <= str2Length; j++) {
                postionArray[i][j] = 0;
            }
        }
        
        
        // 循环 遍历
        for(int i = 1; i <= str1Length; i++) {
            for(int j = 1; j <= str2Length; j ++) {
                // 如果 两个字符 相同
                if (str1[i - 1] == str2[j - 1]) {
                     postionArray[i][j] = postionArray[i - 1][j - 1] + 1;
    
                }
                // 如果 两个 字符 不同
                else {
                   postionArray[i][j] = (postionArray[i - 1][j] > postionArray[i][j - 1]) ? postionArray[i - 1][j] : postionArray[i][j - 1];
                }
                
            }
        }
        
        for (int i = 0; i < str1Length; i++) {
            for (int j = 0; j < str2Length; j++) {
                printf("%d ", postionArray[i][j]);
            }
            printf("
    ");
        }
        
        
        
        int i, j ;
        for (i = str1Length, j = str2Length; i >= 1  && j >= 1;) {
            if (str1[i - 1] == str2[j - 1]) {
                printf("%c ", str1[i - 1]);
                i --;
                j --;
            }
            else {
                if (postionArray[i][j - 1] > postionArray[i - 1][j]) {
                    j--;
                }
                else {
                    i --;
                }
            }
        }
        
        // 释放开辟数组
        for (int i = 0; i < str1Length; i++) {
            free(postionArray[i]);
        }
        free(postionArray);
    }
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            maxPublicSubSequenceTwo("ABCBDAB" , "BDCABA");
        }
        return 0;
    }
    

      给定两个字符串,求出它们之间最长的相同子字符串的长度。

      穷举法:

    #import <Foundation/Foundation.h>
    /**
     找出 两个 字符串 的 最长 公共 子串 (穷举法)
     @param str1 字符串1
     @param str2 字符串2
     */
    void maxPublicSubStringOne(char *str1, char *str2) {
        assert(str1 != NULL && str2 != NULL);
        
        // 起始 位置
        int startPosition = 0;
        // 公共 子串 长度
        int maxStringLength = 0;
        
        // 循环 遍历 所有 子字符串
        for (int i = 0; i < strlen(str1); i ++) {
            for (int j = 0; j < strlen(str2); j++) {
                // 如果 两个 字符 相等
                if(str1[i] == str2[j]) {
                    // 继续 比较 后面的字符
                    int k = 1;
                    while (str1[i + k] == str2[j + k] && str1[i + k] != '' && str2[j + k] != '') {
                        k ++;
                    }
                    // 如果 k 大于 最长 字符串
                    if (k > maxStringLength) {
                        // 公共 子串 长度
                        maxStringLength = k;
                        // 起始位置
                        startPosition = i;
                    }
                }
            }
        }
        
        if(maxStringLength > 0) {
            for (int i = startPosition; i <= maxStringLength; i++) {
                printf("%c ", str1[i]);
            }
        }
    }
    

      动态规划法

    /**
     找出 两个 字符串 的公共 子串(动态规划)
     @param str1 字符串1
     @param str2 字符串2
     */
    void maxPublicSubStringTwo(char *str1, char *str2) {
        assert(str1 != NULL && str2 != NULL);
        
        // 起始 位置
        int startPosition = 0;
        // 公共 子串 长度
        int maxStringLength = 0;
        // 字符串 1 长度
        int str1Length = strlen(str1);
        // 字符串 2 长度
        int str2Length = strlen(str2);
        // 开辟 二维 存储 数组 (并初始化 值为:0)
        
        int **postionArray = (int **)malloc(sizeof(int *) * str1Length);
        
        for (int i = 0; i < str1Length; i ++) {
            postionArray[i] = (int *)malloc(sizeof(int) * str2Length);
        }
        
        for (int i = 0; i < str1Length; i++) {
            for (int j = 0; j < str2Length; j++) {
                postionArray[i][j] = 0;
            }
        }
        
        
        // 循环 遍历
        for(int i = 0; i < str1Length; i++) {
            for(int j = 0; j < str2Length; j ++) {
                // 如果 两个字符 相同
                if (str1[i] == str2[j]) {
                    // 判断 释放 是 边界 情况
                    if (i == 0 || j == 0) {
                        // 边界 情况
                        postionArray[i][j] = 1;
                    }
                    // 非边界 情况
                    else {
                        postionArray[i][j] = postionArray[i - 1][j - 1] + 1;
                    }
                    
                    if (postionArray[i][j] > maxStringLength) {
                        maxStringLength = postionArray[i][j];
                        startPosition = i - postionArray[i][j] + 1;
                    }
                }
                
            }
        }
        
        // 打印 字符串
        if(maxStringLength > 0) {
            for (int i = 0; i <= maxStringLength; i++) {
                printf("%c ", str1[startPosition + i]);
            }
        }
        // 释放开辟数组
        for (int i = 0; i < str1Length; i++) {
            free(postionArray[i]);
        }
        free(postionArray);
    }
    

      

    参考链接:

    求2个字符串的最长公共子序列和最长公共子字符串

    详解动态规划——邹博讲动态规划

     

  • 相关阅读:
    traceroute原理
    IP转发和子网路由
    Dijkstra算法
    String源码学习
    多线程的参数传递
    hbase参数配置优化
    hadoop 点点滴滴(一)
    Win8安装教程!笔记本用U盘安装Win8只需三步
    CentOS 6.4下编译安装MySQL 5.6.14
    Nginx配置文件说明
  • 原文地址:https://www.cnblogs.com/iupoint/p/11576939.html
Copyright © 2020-2023  润新知