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


    版权声明版权归作者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 }
  • 相关阅读:
    appium自动化测试搭建
    How to install Qt Creator on Ubuntu 18.04
    Luci
    OpenWrt 根文件系统启动过程分析
    shell 杂烩
    OpenWrt Luci 调试日志输出的一种方法
    jQuery实现购物车计算价格的方法
    js实现购物车添加,减少数量
    golang-键盘录入数据
    JAVA存储机制(栈、堆、方法区详解)
  • 原文地址:https://www.cnblogs.com/weisteve/p/1806124.html
Copyright © 2020-2023  润新知