全国软件专业人才开发与设计赛题之高难度题“字符串的划分”
版权声明:版权归作者WeiSteven所有,转载请注明!
字符串划分:
首先系统提供一系列的字符串,每个字符串具有一定的权值,切字符串唯一。
求解任意一个字符串的所有可能划分,并输出对应的权值和。
Example:
BaseString.txt内容
a 9
aa 21
aab 33
bc 22
bbc 30
cd 10
cdd 25
待拆分字符串例如:
aaabc
输出:
a aa bc 52
……(还有两种组合,不再列出)
题目难度不大,关键是效率,如果基于字符串的匹配,势必在长字符串的分割匹配查找中的效率极低。
本程序构造了字典树,进而进行字符串的分割操作,效率提高了不少:
参考程序代码:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 /*---------------------------
6 函数需要进行不同字符串的匹配
7 本程序构造一个52个孩子结点的“字典树”
8 字典数的孩子编号通过getIndexByChar()函数获得
9 a b c d……A B C……X Y Z
10 用于快速的对子串匹配工作
11 ---------------------------*/
12
13
14 //构造一个字典数结点
15 struct Node
16 {
17 int value;//纪录树根到此结点的权值
18 Node* next[52];//26*2个字母所对应的下结点
19 };
20
21 //全局变量声明区
22 Node root;
23 char line[100];//存放从文件中读取得数据,然后进行处理对树的维护
24 FILE* stream;//文件描述符
25 char strTo[100];//读取被分析的字符串
26 int var[100];//代表dfs不同深度在字符串串中的间隔长度
27 int varValue[100];
28
29
30 //进行内存的初始化
31 void memNext(Node* r)
32 {
33 for(int i=0;i<52;i++)
34 {
35 r->next[i]=NULL;
36 }
37 }
38
39 //根据字符来获得其索引
40 int getIndexByChar(char t)
41 {
42 if(t>='a'&&t<='z')
43 return t-'a';
44 else if(t>='A'&&t<='Z')
45 {
46 return t-'A'+26;
47 }
48 else
49 return -1;
50 }
51
52 //向数据字典数中插入一条信息
53 void insertItem(char* line)
54 {
55 char st[50];
56 int v;
57 sscanf(line,"%s%d",st,&v);
58 int len=strlen(st);
59 Node* tNode=&root;
60 Node* newNode;
61 char c;
62 for(int i=0;i<len;i++)
63 {
64 c=line[i];
65 if(tNode->next[getIndexByChar(c)]!=NULL)
66 {
67 tNode=tNode->next[getIndexByChar(c)];
68 }
69 else
70 {
71 //新建结点
72 newNode=(Node*)malloc(sizeof(Node));
73 newNode->value=0;
74 memNext(newNode);
75 tNode->next[getIndexByChar(c)]=newNode;
76 tNode=newNode;
77 }
78 }
79 tNode->value=v;
80 }
81
82 //利用递归方法进行内存的释放
83 void deleteNode(Node* node)
84 {
85 if(node!=NULL)
86 {
87 for(int i=0;i<52;i++)
88 {
89 deleteNode(node->next[i]);
90 }
91 free(node);
92 }
93 }
94
95
96 //获取数中对应的权值,不是一个短语则为-1,0代表没这个短语
97 int getValue(char* s)
98 {
99 Node* t=&root;
100 int len=strlen(s);
101 for(int i=0;i<len;i++)
102 {
103 if(t->next[getIndexByChar(s[i])]!=NULL)
104 {
105 t=t->next[getIndexByChar(s[i])];
106 }
107 else
108 {
109 return -1;
110 }
111 }
112 return t->value;
113 }
114
115 //对数据进行处理,试探性的处理,depth代表dfs匹配的深度
116 void dfs(char* str,int depth)
117 {
118 int len=strlen(str);//取得当前点后还有多少字符
119 char* p=strTo;//指针,对字符串进行指示
120 //0个字符,代表已经成功完成,现在要进行显示
121 if(len==0)
122 {
123 int sum=0;
124 for(int i=0;i<depth;i++)
125 {
126 for(int j=0;j<var[i];j++)
127 {
128 printf("%c",*(p++));
129 }
130 putchar(' ');
131 sum+=varValue[i];
132 }
133 printf(" %d\n",sum);
134 }
135 Node* node=&root;
136 {
137 for(int i=0;i<len;i++)
138 {
139 if(node->next[getIndexByChar(str[i])]!=NULL)//不为空,则可以分割
140 {
141 if( node->next[getIndexByChar(str[i])]->value!=0)
142 {
143 var[depth]=i+1;//保存需要间隔的长度
144 varValue[depth]=node->next[getIndexByChar(str[i])]->value;
145 dfs(&str[i+1],depth+1);
146 }
147 node=node->next[getIndexByChar(str[i])];
148 }
149 else
150 {
151 return;
152 }
153 }
154 }
155 }//
156
157 int main()
158 {
159
160 //初始化root中的数值
161 memNext(&root);
162 if((stream = fopen( "BaseString.txt", "r" )) != NULL)
163 {
164 while(fgets( line, 100, stream ) != NULL)
165 {
166 //对字典数进行维护
167 insertItem(line);
168 }
169 }
170
171 scanf("%s",strTo);//读取待分析的字符串
172
173 //printf("%d\n",getValue("bc"));
174
175 dfs(strTo,0);//0代表dfs深度
176
177 for(int i=0;i<52;i++)
178 deleteNode(root.next[i]);
179 return 1;
180 }
2 #include <string.h>
3 #include <stdlib.h>
4
5 /*---------------------------
6 函数需要进行不同字符串的匹配
7 本程序构造一个52个孩子结点的“字典树”
8 字典数的孩子编号通过getIndexByChar()函数获得
9 a b c d……A B C……X Y Z
10 用于快速的对子串匹配工作
11 ---------------------------*/
12
13
14 //构造一个字典数结点
15 struct Node
16 {
17 int value;//纪录树根到此结点的权值
18 Node* next[52];//26*2个字母所对应的下结点
19 };
20
21 //全局变量声明区
22 Node root;
23 char line[100];//存放从文件中读取得数据,然后进行处理对树的维护
24 FILE* stream;//文件描述符
25 char strTo[100];//读取被分析的字符串
26 int var[100];//代表dfs不同深度在字符串串中的间隔长度
27 int varValue[100];
28
29
30 //进行内存的初始化
31 void memNext(Node* r)
32 {
33 for(int i=0;i<52;i++)
34 {
35 r->next[i]=NULL;
36 }
37 }
38
39 //根据字符来获得其索引
40 int getIndexByChar(char t)
41 {
42 if(t>='a'&&t<='z')
43 return t-'a';
44 else if(t>='A'&&t<='Z')
45 {
46 return t-'A'+26;
47 }
48 else
49 return -1;
50 }
51
52 //向数据字典数中插入一条信息
53 void insertItem(char* line)
54 {
55 char st[50];
56 int v;
57 sscanf(line,"%s%d",st,&v);
58 int len=strlen(st);
59 Node* tNode=&root;
60 Node* newNode;
61 char c;
62 for(int i=0;i<len;i++)
63 {
64 c=line[i];
65 if(tNode->next[getIndexByChar(c)]!=NULL)
66 {
67 tNode=tNode->next[getIndexByChar(c)];
68 }
69 else
70 {
71 //新建结点
72 newNode=(Node*)malloc(sizeof(Node));
73 newNode->value=0;
74 memNext(newNode);
75 tNode->next[getIndexByChar(c)]=newNode;
76 tNode=newNode;
77 }
78 }
79 tNode->value=v;
80 }
81
82 //利用递归方法进行内存的释放
83 void deleteNode(Node* node)
84 {
85 if(node!=NULL)
86 {
87 for(int i=0;i<52;i++)
88 {
89 deleteNode(node->next[i]);
90 }
91 free(node);
92 }
93 }
94
95
96 //获取数中对应的权值,不是一个短语则为-1,0代表没这个短语
97 int getValue(char* s)
98 {
99 Node* t=&root;
100 int len=strlen(s);
101 for(int i=0;i<len;i++)
102 {
103 if(t->next[getIndexByChar(s[i])]!=NULL)
104 {
105 t=t->next[getIndexByChar(s[i])];
106 }
107 else
108 {
109 return -1;
110 }
111 }
112 return t->value;
113 }
114
115 //对数据进行处理,试探性的处理,depth代表dfs匹配的深度
116 void dfs(char* str,int depth)
117 {
118 int len=strlen(str);//取得当前点后还有多少字符
119 char* p=strTo;//指针,对字符串进行指示
120 //0个字符,代表已经成功完成,现在要进行显示
121 if(len==0)
122 {
123 int sum=0;
124 for(int i=0;i<depth;i++)
125 {
126 for(int j=0;j<var[i];j++)
127 {
128 printf("%c",*(p++));
129 }
130 putchar(' ');
131 sum+=varValue[i];
132 }
133 printf(" %d\n",sum);
134 }
135 Node* node=&root;
136 {
137 for(int i=0;i<len;i++)
138 {
139 if(node->next[getIndexByChar(str[i])]!=NULL)//不为空,则可以分割
140 {
141 if( node->next[getIndexByChar(str[i])]->value!=0)
142 {
143 var[depth]=i+1;//保存需要间隔的长度
144 varValue[depth]=node->next[getIndexByChar(str[i])]->value;
145 dfs(&str[i+1],depth+1);
146 }
147 node=node->next[getIndexByChar(str[i])];
148 }
149 else
150 {
151 return;
152 }
153 }
154 }
155 }//
156
157 int main()
158 {
159
160 //初始化root中的数值
161 memNext(&root);
162 if((stream = fopen( "BaseString.txt", "r" )) != NULL)
163 {
164 while(fgets( line, 100, stream ) != NULL)
165 {
166 //对字典数进行维护
167 insertItem(line);
168 }
169 }
170
171 scanf("%s",strTo);//读取待分析的字符串
172
173 //printf("%d\n",getValue("bc"));
174
175 dfs(strTo,0);//0代表dfs深度
176
177 for(int i=0;i<52;i++)
178 deleteNode(root.next[i]);
179 return 1;
180 }
作者:W.M.steve
出处:http://www.cnblogs.com/weisteve/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/weisteve/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。