整齐打印
使用等宽字符打印一段文本。输入文本为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 <iostream>
#include <string.h>
#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]<res[j]))
{
res[j]=res[i-1]+cube[i][j];
solution[j]=i; //i为当前行的第一个元素
}
}
}
get_lines(solution,n,number);
//释放内存
delete[] res;
delete[] solution;
for(int i=0;i<=n;i++)
delete[] cube[i];
delete[] cube;
for(int i=0;i<=n;i++)
delete[] space[i];
delete[] space;
}
int get_lines(int solution[],int j,string number[]) //j为当前行的最后一个元素下标
{
int k;
int i=solution[j];
if(i==1) //表示第一个元素
k=1;
else
k=get_lines(solution,i-1,number)+1; //递归
cout<<"current line number is : "<<k<<" ";
for(int l=i;l<=j;l++)
cout<<number[l-1]<<" "; //当前行的第l个元素,str下标为l-1
cout<<endl;
return k;
}
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<n;i++)
{
length[i]=number[i].size();
}
print_neatly(length,number,n,Maxnum);
return 0;
}
编辑距离
算法分析
状态转移函数
$$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 <iostream>
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]<distance.res[i][j])
{
distance.res[i][j]=distance.res[i-1][j-1]+cost[COPY];
distance.solution[i][j]=COPY;
}
if(x[i]!=y[j] && distance.res[i-1][j-1]+cost[REPLACE]<distance.res[i][j])
{
distance.res[i][j]=distance.res[i-1][j-1]+cost[REPLACE];
distance.solution[i][j]=REPLACE;
}
if(i>=2&&j>=2&& x[i]==y[j-1] && x[i-1]==y[j] && distance.res[i-2][j-2]+cost[TWIDDLE]<distance.res[i][j])
{
distance.res[i][j]=distance.res[i-2][j-2]+cost[TWIDDLE];
distance.solution[i][j]=TWIDDLE;
}
if(distance.res[i-1][j]+cost[DELETE]<distance.res[i][j])
{
distance.res[i][j]=distance.res[i-1][j]+cost[DELETE];
distance.solution[i][j]=DELETE;
}
if(distance.res[i][j-1]+cost[INSERT]<distance.res[i][j])
{
distance.res[i][j]=distance.res[i][j-1]+cost[INSERT];
distance.solution[i][j]=INSERT;
}
}
}
//此时序列y[n]的值已经完成,这个时候截取从0<=i<=m-1中最小的kill值
//把m以后的值全部截取掉
for(int i=0;i<=m-1;i++)
{
if(distance.res[i][n]+cost[KILL]<distance.res[m][n]) //相当于调整res[m][n]的值
//判断从哪里开始截断?
{
distance.res[m][n]=distance.res[i][n]+cost[KILL];
distance.solution[m][n]=i;
//从i开始截断,distance.solution[][]提供回溯的点,回溯到哪个点?
}
}
cout<<"distance[m][n]="<<distance.res[m][n]<<" "<<endl;
//输出:
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
cout<<distance.res[i][j]<<" ";
cout<<endl;
}
cout<<endl;
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
PRINT_SOLUTION(distance,i,j);
cout<<endl;
}
cout<<endl;
return distance;
}
void PRINT_sequence(TABLE distance,int i,int j)
{
int I,J;
if(i==0 && j==0)
return;
if(distance.solution[i][j]==COPY || distance.solution[i][j]==REPLACE)
{
I=i-1;
J=j-1;
}
else if(distance.solution[i][j]==TWIDDLE)
{
I=i-2;
J=j-2;
}
else if(distance.solution[i][j]==DELETE)
{
I=i-1;
J=j;
}
else if(distance.solution[i][j]==INSERT)
{
I=i;
J=j-1;
}
else
{
I=distance.solution[i][j];
J=j;
distance.solution[i][j]=KILL;
}
PRINT_sequence(distance,I,J);
PRINT_SOLUTION(distance,i,j);
}
void PRINT_SOLUTION(TABLE distance,int i,int j)
{
if(distance.solution[i][j]==COPY)
cout<<"COPY"<<" ";
else if(distance.solution[i][j]==REPLACE)
cout<<"REPLACE"<<" ";
else if(distance.solution[i][j]==INSERT)
cout<<"INSERT"<<" ";
else if(distance.solution[i][j]==TWIDDLE)
cout<<"TWIDDLE"<<" ";
else
cout<<"KILL"<<" ";
}
count_distance.cpp
#include "count_distance.h"
#include <string.h>
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);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。