整齐打印与编辑距离问题

整齐打印

使用等宽字符打印一段文本。输入文本为n个单词的序列,单词长度为$l_1,l_2, cdots l_n$个字符,将其打印在若干行上,每一行最多$Maxnum$个字符。
如果某行包含第$i$到第$j(i leq j)$个单词,行尾额外空格符的数量是$M-j+i-sum_{k=i}^jl_k$,这个值必须是非负的。

算法分析:

实现过程:

print_neatly.h

#include 
#include 

#define infinity 0x7fffffff

using namespace std;
int get_lines(int solution[],int j,string number[]);

void print_neatly(int length[],string number[],int n,int Maxnum)
{
    int i,j;

    //保存空格数
    int **space;
    space=new int *[n+1];
    for(int i=0;i<=n;i++)
    {
        space[i]=new int [n+1];
    }


    //保存立方值
    int **cube;
    cube=new int *[n+1];
    for(int i=0;i<=n;i++)
    {
        cube[i]=new int [n+1];
    }

    //用于保存解决方案
    int *solution=new int [n+1];

    //初始化获取space[][]的值
    for(int i=1;i<=n;i++)
    {
        space[i][i]=Maxnum-length[i-1];  //这里space[i][]表示第几个数?length[i-1]对应的是下标
        for(int j=i+1;j<=n;j++)
            space[i][j]=space[i][j-1]-length[j-1]-1;
    }

    //获取cube的值,整齐打印是依据cube的值来确定打印距离
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(space[i][j]<0)
                cube[i][j]=infinity;
            else if(j==n && space[i][j]>=0)
                cube[i][j]=0;
            else
                cube[i][j]=space[i][j]*space[i][j]*space[i][j];
        }
    }

    //动态规划过程,将结果存储在res数组中
    int *res=new int [n+1];
    res[0]=0;

    for(int j=1;j<=n;j++)
    {
        res[j]=infinity;
        for(int i=1;i<=j;i++)
        {
            if(res[i-1]!=infinity && cube[i][j]!=infinity && (res[i-1]+cube[i][j]

print_neatly.cpp

#include "print_neatly.h"

int main()
{
    int n=10;  //10个单词
    int Maxnum=8;  //一行可以容纳最多8个字符
    string number[n]={"abc","def","gh","polq","cs","opaqe","klfgh","t","asd","th"};
    int length[n]={0};

    for(int i=0;i

编辑距离

算法分析

状态转移函数

$$res[i,j]=min
begin{cases}
res[i-1,j-1]+copy& text{x[i]==y[j]}\
res[i-1,j-1]+replace& text{x[i]!=y[j]}\
res[i-2,j-2]+twiddle& text{i,j>=2 x[i]==y[j-1] && x[i-1]==y[j]}\
res[i-1,j]+delete& text{other}\
res[i,j-1]+insert& text{other}\
mathop{min}_{0 leq i leq m} {res[i,n]}+kill& text{i==m && j==n}
end{cases}$$

分析方法与“最长公共子序列”问题分析的方法类似。

count_distance.h

#include 
using namespace std;

#define infinity 0x7fffffff


enum {COPY,REPLACE,DELETE,INSERT,TWIDDLE,KILL,TYPE_NUM};

struct TABLE
{
    int **res,**solution;
    TABLE(int m,int n)  //res[m][n] 分别表示图中x_max和y_max
    {
        res=new int *[m+1];
        for(int i=0;i<=m;i++)
            res[i]=new int [n+1];

        solution=new int *[m+1];
        for(int i=0;i<=m;i++)
            solution[i]=new int [n+1];
    }
};

void PRINT_SOLUTION(TABLE distance,int i,int j);

TABLE count_distance(char x[],char y[],int m,int n)
{
    TABLE distance(m,n);
    int cost[TYPE_NUM]={-1,1,2,3,4,-2};

    //初始化
    distance.res[0][0]=0;
    for(int i=0;i<=m;i++)
    {
        distance.res[i][0]=i*cost[DELETE];  //这里不操作y,等于把x中的元素全部删除
        //删除的代价就是 第几个元素×cost
        distance.solution[i][0]=DELETE;
    }
    for(int j=0;j<=n;j++)
    {
        //这里相当于x中没有元素,y[]的值等于插入每一个新的元素
        distance.res[0][j]=j*cost[INSERT];
        distance.solution[0][j]=INSERT;
    }

    //计算最优代价
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            distance.res[i][j]=infinity;
            if(x[i]==y[j] && distance.res[i-1][j-1]+cost[COPY]=2&&j>=2&& x[i]==y[j-1] && x[i-1]==y[j] && distance.res[i-2][j-2]+cost[TWIDDLE]

count_distance.cpp

#include "count_distance.h"
#include 

using namespace std;

int main()
{
    char x[]="algorithm";
    char y[]="altruistic";
    int x_len=strlen(x),y_len=strlen(y);
    TABLE distance=count_distance(x,y,x_len,y_len);
    PRINT_sequence(distance,x_len,y_len);
}

算法实现结果

你可能感兴趣的:(算法导论,动态规划)