要求输入一个字符串,输出所有可以用以上字符串组合而成的组合形式
要求输入一个字符串,输出所有可以用以上字符串组合而成的组合形式,并在其后输出其数字相加之和,如果没有,则不输出。例如输入:aaabc输出:aaabc83aaabc83aa...
要求输入一个字符串,输出所有可以用以上字符串组合而成的组合形式, 并在其后输出其数字相加之和,如果没有,则不输出。
例如输入:aaabc
输出:a aa bc 83
aa a bc 83
aaa bc 41
a a a bc 115 展开
例如输入:aaabc
输出:a aa bc 83
aa a bc 83
aaa bc 41
a a a bc 115 展开
3个回答
展开全部
#include <stdio.h>
#include <string.h>
const int MAX_STRING_LEN = 1000;
struct Token
{
char str[5];
int value;
};
struct Token _tokens[]=
{
{"a",34},
{"aa",36},
{"aaa",28},
{"ab",27},
{"aab",12},
{"bc",13},
{"bbc",25},
{"cd",20},
{"ccd",18}
};
// 计算 tokens 元素个数
int _tokensNum = sizeof(_tokens)/sizeof(struct Token);
/*
如果字符串 str 的子串 str[start,end] 和 _tokens[i].str 匹配
返回 _tokens[i].value
否则返回一个负数
*/
int exist(char str[],int start,int end)
{
int p,i;
for(p = 0 ; p < _tokensNum ; p ++)
{
// 字符串 str 子串的长度和字符串 _tokens[p].str 的长度匹配
if( (end - start + 1) == strlen(_tokens[p].str) )
{
// 逐个字符比较
for(i = 0 ; i < strlen(_tokens[p].str) ; i ++)
{
if(_tokens[p].str[i] != str[i+start])
{
break;
}
}
// 字符串 str 子串和字符串 _tokens[p].str 匹配
if(i == strlen(_tokens[p].str))
{
// printf("%s %d %d\n",_tokens[p].str , start , end);
return _tokens[p].value;
}
}// if
} // for(p)
// 没有匹配
return -1;
}
/*
str : 要分割的字符串
splitPointNum : 分割字符串 str 的分割点个数
splitPoint : 分割字符串 str 的分割点数组
value : 用分割点 splitPoint 分割字符串 str ,获得的所有子串的权值的累加和
counter : 所有分割方法的总数
*/
void split(char str[] ,int splitPointNum ,int splitPoint[],int value , int * counter)
{
int i , j;
int p;
int v = 0;
/*
开始分割的位置
如果已经有分割点 (splitPointNum > 0 ) ,
当前分割点为最后一个分割点 splitPoint[splitPointNum - 1]
否则,从起点 0 开始分割
*/
int startPos = (splitPointNum > 0 ) ? splitPoint[splitPointNum - 1] : 0 ;
// 已经分割完毕
if(startPos >= strlen(str))
{
if(splitPointNum == 0)
{
return ;
}
// for(i = 0 ; i < splitPointNum ; i ++)
// {
// printf("%d ",splitPoint[i]);
// }
// printf("\n");
for(i = 0 , j = 0 ; str[i] != '\0' ; i ++)
{
// 从当前字符开始分割出一个字符,打印一个空格
if(i == splitPoint[j])
{
printf(" ");
j++;
}
printf("%c",str[i]) ;
}
// 输出所有子串的权值的累加和
printf(" %d\n",value);
// 统计
(*counter)++ ;
// 不再递归
return;
}
// 枚举所有可以分割字符串 str 的位置,从 startPos 开始
for(p = startPos ; p < strlen(str) ; p ++)
{
v = exist(str,startPos,p);
// v 大于零,说明从 _tokes 数组中找到一个可以匹配的
if(v > 0)
{
// 添加一个分割点
splitPoint[splitPointNum] = startPos + (p - startPos) + 1;
// 递归
split(str,splitPointNum + 1,splitPoint, value + v,counter);
}
}
}
int main(int argc, char *argv[])
{
char str[MAX_STRING_LEN];
int splitPoint[MAX_STRING_LEN]={0};
int counter = 0;
while(gets(str) != NULL)
{
counter = 0;
split(str,0,splitPoint,0,&counter);
printf("exist %4d split method!\n",counter);
}
return 0;
}
/*
aaabc【input】
a a a bc 115
a aa bc 83
aa a bc 83
aaa bc 41
exist 4 split method!
zzz【input】
exist 0 split method!
aaabcbcaa【input】
a a a bc bc a a 196
a a a bc bc aa 164
a aa bc bc a a 164
a aa bc bc aa 132
aa a bc bc a a 164
aa a bc bc aa 132
aaa bc bc a a 122
aaa bc bc aa 90
exist 8 split method!
*/
#include <string.h>
const int MAX_STRING_LEN = 1000;
struct Token
{
char str[5];
int value;
};
struct Token _tokens[]=
{
{"a",34},
{"aa",36},
{"aaa",28},
{"ab",27},
{"aab",12},
{"bc",13},
{"bbc",25},
{"cd",20},
{"ccd",18}
};
// 计算 tokens 元素个数
int _tokensNum = sizeof(_tokens)/sizeof(struct Token);
/*
如果字符串 str 的子串 str[start,end] 和 _tokens[i].str 匹配
返回 _tokens[i].value
否则返回一个负数
*/
int exist(char str[],int start,int end)
{
int p,i;
for(p = 0 ; p < _tokensNum ; p ++)
{
// 字符串 str 子串的长度和字符串 _tokens[p].str 的长度匹配
if( (end - start + 1) == strlen(_tokens[p].str) )
{
// 逐个字符比较
for(i = 0 ; i < strlen(_tokens[p].str) ; i ++)
{
if(_tokens[p].str[i] != str[i+start])
{
break;
}
}
// 字符串 str 子串和字符串 _tokens[p].str 匹配
if(i == strlen(_tokens[p].str))
{
// printf("%s %d %d\n",_tokens[p].str , start , end);
return _tokens[p].value;
}
}// if
} // for(p)
// 没有匹配
return -1;
}
/*
str : 要分割的字符串
splitPointNum : 分割字符串 str 的分割点个数
splitPoint : 分割字符串 str 的分割点数组
value : 用分割点 splitPoint 分割字符串 str ,获得的所有子串的权值的累加和
counter : 所有分割方法的总数
*/
void split(char str[] ,int splitPointNum ,int splitPoint[],int value , int * counter)
{
int i , j;
int p;
int v = 0;
/*
开始分割的位置
如果已经有分割点 (splitPointNum > 0 ) ,
当前分割点为最后一个分割点 splitPoint[splitPointNum - 1]
否则,从起点 0 开始分割
*/
int startPos = (splitPointNum > 0 ) ? splitPoint[splitPointNum - 1] : 0 ;
// 已经分割完毕
if(startPos >= strlen(str))
{
if(splitPointNum == 0)
{
return ;
}
// for(i = 0 ; i < splitPointNum ; i ++)
// {
// printf("%d ",splitPoint[i]);
// }
// printf("\n");
for(i = 0 , j = 0 ; str[i] != '\0' ; i ++)
{
// 从当前字符开始分割出一个字符,打印一个空格
if(i == splitPoint[j])
{
printf(" ");
j++;
}
printf("%c",str[i]) ;
}
// 输出所有子串的权值的累加和
printf(" %d\n",value);
// 统计
(*counter)++ ;
// 不再递归
return;
}
// 枚举所有可以分割字符串 str 的位置,从 startPos 开始
for(p = startPos ; p < strlen(str) ; p ++)
{
v = exist(str,startPos,p);
// v 大于零,说明从 _tokes 数组中找到一个可以匹配的
if(v > 0)
{
// 添加一个分割点
splitPoint[splitPointNum] = startPos + (p - startPos) + 1;
// 递归
split(str,splitPointNum + 1,splitPoint, value + v,counter);
}
}
}
int main(int argc, char *argv[])
{
char str[MAX_STRING_LEN];
int splitPoint[MAX_STRING_LEN]={0};
int counter = 0;
while(gets(str) != NULL)
{
counter = 0;
split(str,0,splitPoint,0,&counter);
printf("exist %4d split method!\n",counter);
}
return 0;
}
/*
aaabc【input】
a a a bc 115
a aa bc 83
aa a bc 83
aaa bc 41
exist 4 split method!
zzz【input】
exist 0 split method!
aaabcbcaa【input】
a a a bc bc a a 196
a a a bc bc aa 164
a aa bc bc a a 164
a aa bc bc aa 132
aa a bc bc a a 164
aa a bc bc aa 132
aaa bc bc a a 122
aaa bc bc aa 90
exist 8 split method!
*/
展开全部
题看懂了 有点难 先想想 做个标记
追问
大神 救命啊
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
a aa bc这些字母对应的 数字 34,36,13是不是规定好的??
更多追问追答
追问
是啊 看那个图片规定, a 对应 34 , aa 对应 36 , 以此类推
追答
最后两位一定是bc和着对吧??
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询