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

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

 

 

 

你可能感兴趣的:(全国软件专业人才开发与设计赛题之高难度题“字符串的划分”)