CSDN编程挑战里的题目

例如有一个字符串"iinbinbing",截取不同位置的字符‘b’、‘i’、‘n’、‘g’组合成单词"bing"。
若从1开始计数的话,则‘b’ ‘i’ ‘n’ ‘g’这4个字母出现的位置分别为(4,5,6,10) (4,5,9,10),
(4,8,9,10)和(7,8,9,10),故总共可以组合成4个单词”bing“。
问题是:现给定任意字符串,只包含小写‘b’ ‘i’ ‘n’ ‘g’这4种字母,请问一共能组合成多少个单词bing?

字符串长度不超过10000,由于结果可能比较大,请输出对10^9 + 7取余数之后的结果。

这个问题写个四重循环就可以.只是效率方面还有待优化.

第一版代码:

  1 #include <stdio.h>
  2 #include <iostream>
  3 #include <string>
  4
  5 #include <cstring>
  6 #include <cstdio>
  7
  8 #define BING_MAX 1000000007
  9
 10 int Bing(const char* szBing)
 11 {
 12     if (!szBing || !szBing[0])
 13     {
 14         return 0;
 15     }
 16
 17     int len = (int)strlen(szBing);
 18     int* listPosB = (int*)malloc(len*sizeof(int));
 19     int* listPosI = (int*)malloc(len*sizeof(int));
 20     int* listPosN = (int*)malloc(len*sizeof(int));
 21     int* listPosG = (int*)malloc(len*sizeof(int));
 22     memset(listPosB, 0, len*sizeof(int));
 23     memset(listPosI, 0, len*sizeof(int));
 24     memset(listPosN, 0, len*sizeof(int));
 25     memset(listPosG, 0, len*sizeof(int));
 26     int numB = 0;
 27     int numI = 0;
 28     int numN = 0;
 29     int numG = 0;
 30
 31     for (int i = 0; i < len; i++)
 32     {
 33         switch (szBing[i])
 34         {
 35         case 'B':
 36         case 'b':
 37             listPosB[numB] = i;
 38             numB++;
 39             break;
 40         case 'I':
 41         case 'i':
 42             listPosI[numI] = i;
 43             numI++;
 44             break;
 45         case 'N':
 46         case 'n':
 47             listPosN[numN] = i;
 48             numN++;
 49             break;
 50         case 'G':
 51         case 'g':
 52             listPosG[numG] = i;
 53             numG++;
 54             break;
 55         }
 56     }
 57
 58     int count = 0;
 59
 60     int startB;
 61     int startI;
 62     int startN;
 63     int startG;
 64     for (int b = 0; b < numB; b++)
 65     {
 66         startB = listPosB[b];
 67
 68         for (int i = 0; i < numI; i++)
 69         {
 70             startI = listPosI[i];
 71             if (startI < startB)
 72             {
 73                 continue;
 74             }
 75
 76             for (int n = 0; n < numN; n++)
 77             {
 78                 startN = listPosN[n];
 79                 if (startN < startI)
 80                 {
 81                     continue;
 82                 }
 83
 84                 for (int g = 0; g < numG; g++)
 85                 {
 86                     startG = listPosG[g];
 87                     if (startG < startN)
 88                     {
 89                         continue;
 90                     }
 91
 92                     count++;
 93                     if (count > BING_MAX)
 94                     {
 95                         count -= BING_MAX;
 96                     }
 97                 }
 98             }
 99         }
100     }
101
102     free(listPosB);
103     free(listPosI);
104     free(listPosN);
105     free(listPosG);
106
107     return count;
108 }

优化后的代码:

  1 #include <cstring>
  2 #include <cstdio>
  3
  4 #define BING_MAX 1000000007
  5
  6 struct U2
  7 {
  8     short pos;
  9     short next;
 10 };
 11
 12 int Bing(const char* szBing)
 13 {
 14     if (!szBing || !szBing[0])
 15     {
 16         return 0;
 17     }
 18
 19     int len = (int)strlen(szBing);
 20     U2* listPosB = (U2*)malloc(len*sizeof(U2));
 21     U2* listPosI = (U2*)malloc(len*sizeof(U2));
 22     U2* listPosN = (U2*)malloc(len*sizeof(U2));
 23     U2* listPosG = (U2*)malloc(len*sizeof(U2));
 24     memset(listPosB, 0, len*sizeof(int));
 25     memset(listPosI, 0, len*sizeof(int));
 26     memset(listPosN, 0, len*sizeof(int));
 27     memset(listPosG, 0, len*sizeof(int));
 28     int numB = 0;
 29     int numI = 0;
 30     int numN = 0;
 31     int numG = 0;
 32
 33     for (int i = 0; i < len; i++)
 34     {
 35         switch (szBing[i])
 36         {
 37         case 'B':
 38         case 'b':
 39             listPosB[numB].pos = (short)i;
 40             numB++;
 41             break;
 42         case 'I':
 43         case 'i':
 44             listPosI[numI].pos = (short)i;
 45             numI++;
 46             break;
 47         case 'N':
 48         case 'n':
 49             listPosN[numN].pos = (short)i;
 50             numN++;
 51             break;
 52         case 'G':
 53         case 'g':
 54             listPosG[numG].pos = (short)i;
 55             numG++;
 56             break;
 57         }
 58     }
 59
 60     for (int i = 0; i < numB; i++)
 61     {
 62         for (int j = 0; j < numI; j++)
 63         {
 64             if (listPosB[i].pos < listPosI[j].pos)
 65             {
 66                 listPosB[i].next = j;
 67                 break;
 68             }
 69         }
 70     }
 71
 72     for (int i = 0; i < numI; i++)
 73     {
 74         for (int j = 0; j < numN; j++)
 75         {
 76             if (listPosI[i].pos < listPosN[j].pos)
 77             {
 78                 listPosI[i].next = j;
 79                 break;
 80             }
 81         }
 82     }
 83
 84     for (int i = 0; i < numN; i++)
 85     {
 86         for (int j = 0; j < numG; j++)
 87         {
 88             if (listPosN[i].pos < listPosG[j].pos)
 89             {
 90                 listPosN[i].next = j;
 91                 break;
 92             }
 93         }
 94     }
 95
 96     int count = 0;
 97     for (int b = 0; b < numB; b++)
 98     {
 99         for (int i = listPosB[b].next; i < numI; i++)
100         {
101             for (int n = listPosI[i].next; n < numN; n++)
102             {
103                 for (int g = listPosN[n].next; g < numG; g++)
104                 {
105                     count++;
106                     if (count > BING_MAX)
107                     {
108                         count -= BING_MAX;
109                     }
110                 }
111             }
112         }
113     }
114
115     /*
116     short startB;
117     short startI;
118     short startN;
119     short startG;
120     for (int b = 0; b < numB; b++)
121     {
122         startB = listPosB[b].pos;
123
124         for (int i = 0; i < numI; i++)
125         {
126             startI = listPosI[i].pos;
127             if (startI < startB)
128             {
129                 continue;
130             }
131
132             for (int n = 0; n < numN; n++)
133             {
134                 startN = listPosN[n].pos;
135                 if (startN < startI)
136                 {
137                     continue;
138                 }
139
140                 for (int g = 0; g < numG; g++)
141                 {
142                     startG = listPosG[g].pos;
143                     if (startG < startN)
144                     {
145                         continue;
146                     }
147
148                     count++;
149                     if (count > BING_MAX)
150                     {
151                         count -= BING_MAX;
152                     }
153                 }
154             }
155         }
156     }
157     */
158
159     free(listPosB);
160     free(listPosI);
161     free(listPosN);
162     free(listPosG);
163
164     return count;
165 }

第三版优化,还是运行时间超过3s,我是真没辙了.

  1 #include <cstring>
  2 #include <cstdio>
  3 #include <assert.h>
  4
  5 #define BING_MAX 1000000007
  6
  7 struct U2
  8 {
  9     short pos;
 10     short next;
 11 };
 12
 13 int Bing(const char* szBing, int len)
 14 {
 15     if (!szBing || !szBing[0])
 16     {
 17         return 0;
 18     }
 19
 20     U2* listPosB = (U2*)malloc(len*sizeof(U2));
 21     U2* listPosI = (U2*)malloc(len*sizeof(U2));
 22     U2* listPosN = (U2*)malloc(len*sizeof(U2));
 23     U2* listPosG = (U2*)malloc(len*sizeof(U2));
 24     memset(listPosB, 0, len*sizeof(int));
 25     memset(listPosI, 0, len*sizeof(int));
 26     memset(listPosN, 0, len*sizeof(int));
 27     memset(listPosG, 0, len*sizeof(int));
 28     int numB = 0;
 29     int numI = 0;
 30     int numN = 0;
 31     int numG = 0;
 32
 33     for (int i = 0; i < len; i++)
 34     {
 35         if (szBing[i] == 'b')
 36         {
 37             listPosB[numB].pos = (short)i;
 38             numB++;
 39         }
 40         else if  (szBing[i] == 'i')
 41         {
 42             listPosI[numI].pos = (short)i;
 43             numI++;
 44         }
 45         else if  (szBing[i] == 'n')
 46         {
 47             listPosN[numN].pos = (short)i;
 48             numN++;
 49         }
 50         else
 51         {
 52             listPosG[numG].pos = (short)i;
 53             numG++;
 54         }
 55     }
 56
 57     int t = 0;
 58     for (int i = 0; i < numB; i++)
 59     {
 60         for (int j = t; j < numI; j++)
 61         {
 62             if (listPosB[i].pos < listPosI[j].pos)
 63             {
 64                 listPosB[i].next = t = j;
 65                 break;
 66             }
 67         }
 68     }
 69
 70     t = 0;
 71     for (int i = 0; i < numI; i++)
 72     {
 73         for (int j = t; j < numN; j++)
 74         {
 75             if (listPosI[i].pos < listPosN[j].pos)
 76             {
 77                 listPosI[i].next = t = j;
 78                 break;
 79             }
 80         }
 81     }
 82
 83     t = 0;
 84     for (int i = 0; i < numN; i++)
 85     {
 86         for (int j = t; j < numG; j++)
 87         {
 88             if (listPosN[i].pos < listPosG[j].pos)
 89             {
 90                 listPosN[i].next = t = j;
 91                 break;
 92             }
 93         }
 94     }
 95
 96     int count = 0;
 97     for (int b = 0; b < numB; b++)
 98     {
 99         for (int i = listPosB[b].next; i < numI; i++)
100         {
101             for (int n = listPosI[i].next; n < numN; n++)
102             {
103                 count += numG - listPosN[n].next;
104             }
105         }
106
107         if (count > BING_MAX)
108         {
109             count -= BING_MAX;
110         }
111     }
112
113     free(listPosB);
114     free(listPosI);
115     free(listPosN);
116     free(listPosG);
117
118     return count;
119 }

第四版代码:

  1 #include <cstring>
  2 #include <cstdio>
  3
  4 #define BING_MAX 1000000007
  5
  6 struct U2
  7 {
  8     int pos;
  9     int count;
 10 };
 11
 12 int Bing(const char* szBing, int len)
 13 {
 14     if (!szBing || !szBing[0])
 15     {
 16         return 0;
 17     }
 18
 19     U2* listPosB = (U2*)malloc(len*sizeof(U2));
 20     U2* listPosI = (U2*)malloc(len*sizeof(U2));
 21     U2* listPosN = (U2*)malloc(len*sizeof(U2));
 22     U2* listPosG = (U2*)malloc(len*sizeof(U2));
 23     memset(listPosB, 0, len*sizeof(int));
 24     memset(listPosI, 0, len*sizeof(int));
 25     memset(listPosN, 0, len*sizeof(int));
 26     memset(listPosG, 0, len*sizeof(int));
 27     int numB = 0;
 28     int numI = 0;
 29     int numN = 0;
 30     int numG = 0;
 31
 32     for (int i = 0; i < len; i++)
 33     {
 34         if (szBing[i] == 'b')
 35         {
 36             listPosB[numB].pos = i;
 37             numB++;
 38         }
 39         else if  (szBing[i] == 'i')
 40         {
 41             listPosI[numI].pos = i;
 42             numI++;
 43         }
 44         else if  (szBing[i] == 'n')
 45         {
 46             listPosN[numN].pos = i;
 47             numN++;
 48         }
 49         else if  (szBing[i] == 'g')
 50         {
 51             listPosG[numG].pos = i;
 52             numG++;
 53         }
 54     }
 55
 56     int b = 0;
 57     int i = 0;
 58     int n = 0;
 59     int g = 0;
 60     int t;
 61
 62     // 每个N之后有多少个G的选择
 63     for (n = 0; n < numN; n++)
 64     {
 65         while (listPosG[g].pos < listPosN[n].pos && g < numG)
 66         {
 67             g++;
 68         }
 69         listPosN[n].count = numG - g;
 70     }
 71
 72     // 每个I之后有多少个NG的选择
 73     n = 0;
 74     for (i = 0; i < numI; i++)
 75     {
 76         while (listPosN[n].pos < listPosI[i].pos && n < numN)
 77         {
 78             n++;
 79         }
 80         listPosI[i].count = 0;
 81         for (t = n; t < numN; t++)
 82         {
 83             listPosI[i].count += listPosN[t].count;
 84         }
 85     }
 86
 87     // 每个B之后有多少个ING的选择
 88     i = 0;
 89     int count = 0;
 90     for (int b = 0; b < numB; b++)
 91     {
 92         while (listPosI[i].pos < listPosB[b].pos && i < numI)
 93         {
 94             i++;
 95         }
 96         listPosB[b].count = 0;
 97         for (t = i; t < numI; t++)
 98         {
 99             listPosB[b].count += listPosI[t].count;
100         }
101
102         count += listPosB[b].count;
103         if (count > BING_MAX)
104         {
105             count -= BING_MAX;
106         }
107     }
108
109     free(listPosB);
110     free(listPosI);
111     free(listPosN);
112     free(listPosG);
113
114     return count;
115 }

终于想到正确答案了,原来我一开始就误入歧途了,最早的代码算法复杂度是O(n^4),我将其优化到O(n^2),然后又优化到O(n*log(n)),而最终代码的复杂度是O(n).

 1 #define BING_MAX 1000000007
 2
 3 int Bing(const char* szBing)
 4 {
 5     int numB = 0;
 6     int numI = 0;
 7     int numN = 0;
 8     int numG = 0;
 9     int pos = 0;
10     while (szBing[pos])
11     {
12         if (szBing[pos] == 'b')
13         {
14             numB++;
15         }
16         else if (szBing[pos] == 'i')
17         {
18             numI += numB;
19         }
20         else if (szBing[pos] == 'n')
21         {
22             numN += numI;
23         }
24         else if (szBing[pos] == 'g')
25         {
26             numG += numN;
27             if (numG > BING_MAX)
28             {
29                 numG -= BING_MAX;
30             }
31         }
32         pos++;
33     }
34
35     return numG;
36 }

给定任意字符串,计算一共能组合成多少个单词bing相关推荐

  1. python编写函数、给定任意字符串_编写函数,给定任意字符串,找出其中只出现一次的字符,如果有多个这样的字符,就全部找出。...

    [简答题]编写程序,实现分段函数计算,如下表所示. x y x<0 0 0<=x<5 x 5<=x<10 3x-5 10<=x<20 0.5x-2 20< ...

  2. 【第75题】给定一个字符串,将它转换成整数

    文章目录 一.题目描述 二.解题思路 三.代码详解 一.题目描述   实现一个myAtoi(string s)函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数 ...

  3. 2道编程题:1.给定一个字符串,计算字符串中数值的个数并求和。

    // 转载于:https://www.cnblogs.com/BlueBlue-Sky/p/8495420.html

  4. Python查找任意字符串中只出现一次的字符(2016奇虎笔试题)

    '''    程序功能:    编写函数,给定任意字符串,找出其中只出现一次的字符,    如果有多个这样的字符,就全部找出.''' import sys def searchOne(s):     ...

  5. R语言paste函数、paste0函数将多个输入组合成字符串实战

    R语言paste函数.paste0函数将多个输入组合成字符串实战 目录 R语言paste函数.paste0函数将多个输入组合成字符串实战 #基本语法

  6. Python练习题:---给定一个字符串 {xxx[xxx{xxx}]xx{x[xxx]xxx{xxx}xx}x} 判断其中的 {}[]() 是否成对出现

    给定一个字符串 {xxx[xxx{xxx}]xx{x[xxx]xxx{xxx}xx}x} 判断其中的 {} 是否成对出现 答题思路: 使用堆栈进行解决 我们首先压栈一个左括号,当什么时候检测到与之对应 ...

  7. java 字符串排列组合_Java 程序计算列出字符串的所有排列组合

    Java 程序计算列出字符串的所有排列组合 在此示例中,我们将学习计算Java中字符串的所有排列组合. 要理解此示例,您应该了解以下Java编程主题: 字符串的排列是指可以通过互换字符串字符的位置来形 ...

  8. 递归法:计算m个A,n个B可以组合成多少种排列问题?

    问题:计算m个A,n个B可以组合成多少种排列问题? 假设:计算3个A,2个B可以组合成多少种排列问题? 举例:AAABB BABAA- 方法:采取分割思想将第一个与后面的分开,划分为两部分,变得好解决 ...

  9. Oracle任意字符串转换成拼音首字母简写

    Oracle任意字符串转换成拼音首字母简写 需求目标 将"拼音简码"四个字转换成拼音首字母简写PYJM 实现代码 CREATE OR REPLACE FUNCTION FUN_GE ...

最新文章

  1. C# winform单元格的formatted值的类型错误 DataGridView中CheckBox列运行时候System.FormatException异常
  2. Halcon初学者知识【5】画若干个圆
  3. 修改Maven源为阿里巴巴的镜像
  4. shiro 拦截未登录的ajax_Shiro是如何拦截未登录请求的(二)
  5. WordPress的基本知识
  6. Linux安装python3.8时,编译过程中报错Could not build the ssl module!
  7. centos node 进程保护_NodeJs之进程守护
  8. Web前端课程的学习内容有哪些?
  9. 程序员,我要为了这个名号而疯狂
  10. 生命如歌-五年级每日一记
  11. Android的变化过程~
  12. Ubuntu 20.04切换软件源为清华源
  13. 贪心——Greedy
  14. 再获认可|九州云获评2022分布式云与云边协同创新实践案例
  15. EI 期刊目录 下载和查询方法(很简单)
  16. CodeForces - 1042C (emmmmmm水题)
  17. elasticsearch最全详细使用教程:搜索详解
  18. 井底之蛙,还需努力|记此次去杭州参加AEIC计算机与机械制造类会议有感
  19. 黑苹果安装教程,教您黑苹果怎么安装
  20. windows版 nginx配置反向代理实例教程 跳转tomcat和php网站

热门文章

  1. Python学习系列:PyCharm CE 安装与测试
  2. CSS3基础知识(一)
  3. Arduino MEGA 2560找不到驱动怎么办
  4. jsp页面点击显示影藏div的一个方法
  5. ASP.NET MVC3 控制器
  6. [转]删除表中重复记录
  7. c++中vector使用说明
  8. IOS15仿微信我的页面
  9. java根据文件路径读取文件_java根据路径读取文件
  10. redis延迟队列 实现_php使用redis的有序集合zset实现延迟队列