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

本文主要是介绍全国软件专业人才开发与设计赛题之高难度题“字符串的划分”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

 

 

 

这篇关于全国软件专业人才开发与设计赛题之高难度题“字符串的划分”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/678578

相关文章

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python中的可视化设计与UI界面实现

《Python中的可视化设计与UI界面实现》本文介绍了如何使用Python创建用户界面(UI),包括使用Tkinter、PyQt、Kivy等库进行基本窗口、动态图表和动画效果的实现,通过示例代码,展示... 目录从像素到界面:python带你玩转UI设计示例:使用Tkinter创建一个简单的窗口绘图魔法:用

python修改字符串值的三种方法

《python修改字符串值的三种方法》本文主要介绍了python修改字符串值的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录第一种方法:第二种方法:第三种方法:在python中,字符串对象是不可变类型,所以我们没办法直接

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

C#中字符串分割的多种方式

《C#中字符串分割的多种方式》在C#编程语言中,字符串处理是日常开发中不可或缺的一部分,字符串分割是处理文本数据时常用的操作,它允许我们将一个长字符串分解成多个子字符串,本文给大家介绍了C#中字符串分... 目录1. 使用 string.Split2. 使用正则表达式 (Regex.Split)3. 使用

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件