给定任意字符串,计算一共能组合成多少个单词bing
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相关推荐
- python编写函数、给定任意字符串_编写函数,给定任意字符串,找出其中只出现一次的字符,如果有多个这样的字符,就全部找出。...
[简答题]编写程序,实现分段函数计算,如下表所示. x y x<0 0 0<=x<5 x 5<=x<10 3x-5 10<=x<20 0.5x-2 20< ...
- 【第75题】给定一个字符串,将它转换成整数
文章目录 一.题目描述 二.解题思路 三.代码详解 一.题目描述 实现一个myAtoi(string s)函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数 ...
- 2道编程题:1.给定一个字符串,计算字符串中数值的个数并求和。
// 转载于:https://www.cnblogs.com/BlueBlue-Sky/p/8495420.html
- Python查找任意字符串中只出现一次的字符(2016奇虎笔试题)
''' 程序功能: 编写函数,给定任意字符串,找出其中只出现一次的字符, 如果有多个这样的字符,就全部找出.''' import sys def searchOne(s): ...
- R语言paste函数、paste0函数将多个输入组合成字符串实战
R语言paste函数.paste0函数将多个输入组合成字符串实战 目录 R语言paste函数.paste0函数将多个输入组合成字符串实战 #基本语法
- Python练习题:---给定一个字符串 {xxx[xxx{xxx}]xx{x[xxx]xxx{xxx}xx}x} 判断其中的 {}[]() 是否成对出现
给定一个字符串 {xxx[xxx{xxx}]xx{x[xxx]xxx{xxx}xx}x} 判断其中的 {} 是否成对出现 答题思路: 使用堆栈进行解决 我们首先压栈一个左括号,当什么时候检测到与之对应 ...
- java 字符串排列组合_Java 程序计算列出字符串的所有排列组合
Java 程序计算列出字符串的所有排列组合 在此示例中,我们将学习计算Java中字符串的所有排列组合. 要理解此示例,您应该了解以下Java编程主题: 字符串的排列是指可以通过互换字符串字符的位置来形 ...
- 递归法:计算m个A,n个B可以组合成多少种排列问题?
问题:计算m个A,n个B可以组合成多少种排列问题? 假设:计算3个A,2个B可以组合成多少种排列问题? 举例:AAABB BABAA- 方法:采取分割思想将第一个与后面的分开,划分为两部分,变得好解决 ...
- Oracle任意字符串转换成拼音首字母简写
Oracle任意字符串转换成拼音首字母简写 需求目标 将"拼音简码"四个字转换成拼音首字母简写PYJM 实现代码 CREATE OR REPLACE FUNCTION FUN_GE ...
最新文章
- C# winform单元格的formatted值的类型错误 DataGridView中CheckBox列运行时候System.FormatException异常
- Halcon初学者知识【5】画若干个圆
- 修改Maven源为阿里巴巴的镜像
- shiro 拦截未登录的ajax_Shiro是如何拦截未登录请求的(二)
- WordPress的基本知识
- Linux安装python3.8时,编译过程中报错Could not build the ssl module!
- centos node 进程保护_NodeJs之进程守护
- Web前端课程的学习内容有哪些?
- 程序员,我要为了这个名号而疯狂
- 生命如歌-五年级每日一记
- Android的变化过程~
- Ubuntu 20.04切换软件源为清华源
- 贪心——Greedy
- 再获认可|九州云获评2022分布式云与云边协同创新实践案例
- EI 期刊目录 下载和查询方法(很简单)
- CodeForces - 1042C (emmmmmm水题)
- elasticsearch最全详细使用教程:搜索详解
- 井底之蛙,还需努力|记此次去杭州参加AEIC计算机与机械制造类会议有感
- 黑苹果安装教程,教您黑苹果怎么安装
- windows版 nginx配置反向代理实例教程 跳转tomcat和php网站