字符串合并顺序不一样产生成本不一样,例如hello,hi,good,如果我们先合并hi和good在合并hello,那么成本是6+11=17,如果先good和hello再hi,那么成本是9+11=20;
所以我们采用贪心算法来合并字符串,主要思想是每次选取最短的字符串进行合并,最后输出,也可以认为是构建哈夫曼树。
我采取的是数组进行模拟这个过程,每次合成以后把合成的字符串放回字符串里面然后再次排序选最小的两个不断合成,直到只有一个字符串。
代码实现
#include<iostream>
#include "string.h"
using namespace std;
int main()
{
char str[10][40]={0};
int min=0;
int o=0;//标志位
int i,u;
int l=0;
int n=1;
printf("请输入字符串数量\n");
scanf("%d",&i);
for(u=0;u<i;u++)//输入字符串
{
scanf("%s",str[u]);
}
int sum=u;
while(u>1)//不断循环直到字符串变为一串
{
if(o==0)//对字符串数组进行排序,大的在后面
{
char temp[30];
for(int c=0;c<u;c++)
{
for(int b=c+1;b<u;b++)
{
if(strlen(str[c])>strlen(str[b]))
{
strcpy(temp, str[b]);
strcpy(str[b], str[c]);
strcpy(str[c], temp);
}
}
}
}
if(o==1)//也是排序,但是还可以控制字符连接的顺序;//可以这一个if全部去掉
{
char tem[30];
int x=0;
while(x < 10 && str[x][0] != '\0')
{
x++;
};
//printf("%d\n",x);
strcpy(tem, str[0]);
strcpy(str[0], str[--x]);
strcpy(str[x], tem);
for(int cc=1;cc<u;cc++)
{
for(int bb=cc+1;bb<u;bb++)
{
if(strlen(str[cc])>strlen(str[bb]))
{
strcpy(tem, str[bb]);
strcpy(str[bb], str[cc]);
strcpy(str[cc], tem);
}
}
}
}
int m=0;//对数组进行判空
while(m < 10 && str[m][0] != '\0')
{
m++;
}
int a=0;
int b=0;
for(int k=0;k<strlen(str[0])+strlen(str[1]);k++)//合成字符串
{
if(str[0][a]!='\0')
str[m][k]=str[0][a++];
else
str[m][k]=str[1][b++];
}
printf("%s+%s=%s\n",str[0],str[1],str[m]);//输出合成过程
min+=strlen(str[0])+strlen(str[1]);//将合成字符串的最小成本相加
strcpy(str[0], "");//赋空
strcpy(str[1], "");
//移0操作
u--;//循环控制变量
for(int c=0;c<u;c++)//赋空以后将字符串数组不是空的字符串前移
{
if(str[c][0]=='\0')
{
int b=c;
int yy=0;
while(b < 10 && str[b][0] == '\0')
{
b++;
}
strcpy(str[c], str[b]);
strcpy(str[b], "");
}
}
o++;
}
printf("最小成本=%d\n",min);
return 0;
}
运行结果
测试用例:red, blue,yellow
测试用例:mango,lemon,orange,tangerine,lime
因为是数组,溢出在字符串个数超出10,全部字符串长度加起来大于40, 代码很乱,请多多见谅。