全国软件专业人才开发与设计赛题之高难度题“字符串的划分”

版权声明版权归作者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 }

 

 

 

posted @ 2010-08-23 08:50  Eric.wei  阅读(691)  评论(3编辑  收藏  举报