本文主要是介绍全国软件专业人才开发与设计赛题之高难度题“字符串的划分”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
版权声明:版权归作者WeiSteven所有,转载请注明!
字符串划分:
首先系统提供一系列的字符串,每个字符串具有一定的权值,切字符串唯一。
求解任意一个字符串的所有可能划分,并输出对应的权值和。
Example:
BaseString.txt内容
a 9
aa 21
aab 33
bc 22
bbc 30
cd 10
cdd 25
待拆分字符串例如:
aaabc
输出:
a aa bc 52
……(还有两种组合,不再列出)
题目难度不大,关键是效率,如果基于字符串的匹配,势必在长字符串的分割匹配查找中的效率极低。
本程序构造了字典树,进而进行字符串的分割操作,效率提高了不少:
参考程序代码:
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 }
这篇关于全国软件专业人才开发与设计赛题之高难度题“字符串的划分”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!