给定任意字符串,计算一共能组合成多少个单词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取余数之后的结果。
这个问题写个四重循环就可以.只是效率方面还有待优化.
第一版代码:
#include <stdio.h>
#include <iostream>
#include <string> #include <cstring>
#include <cstdio> #define BING_MAX 1000000007 int Bing(const char* szBing)
{
if (!szBing || !szBing[])
{
return ;
} int len = (int)strlen(szBing);
int* listPosB = (int*)malloc(len*sizeof(int));
int* listPosI = (int*)malloc(len*sizeof(int));
int* listPosN = (int*)malloc(len*sizeof(int));
int* listPosG = (int*)malloc(len*sizeof(int));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
switch (szBing[i])
{
case 'B':
case 'b':
listPosB[numB] = i;
numB++;
break;
case 'I':
case 'i':
listPosI[numI] = i;
numI++;
break;
case 'N':
case 'n':
listPosN[numN] = i;
numN++;
break;
case 'G':
case 'g':
listPosG[numG] = i;
numG++;
break;
}
} int count = ; int startB;
int startI;
int startN;
int startG;
for (int b = ; b < numB; b++)
{
startB = listPosB[b]; for (int i = ; i < numI; i++)
{
startI = listPosI[i];
if (startI < startB)
{
continue;
} for (int n = ; n < numN; n++)
{
startN = listPosN[n];
if (startN < startI)
{
continue;
} for (int g = ; g < numG; g++)
{
startG = listPosG[g];
if (startG < startN)
{
continue;
} count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}
优化后的代码:
#include <cstring>
#include <cstdio> #define BING_MAX 1000000007 struct U2
{
short pos;
short next;
}; int Bing(const char* szBing)
{
if (!szBing || !szBing[])
{
return ;
} int len = (int)strlen(szBing);
U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
switch (szBing[i])
{
case 'B':
case 'b':
listPosB[numB].pos = (short)i;
numB++;
break;
case 'I':
case 'i':
listPosI[numI].pos = (short)i;
numI++;
break;
case 'N':
case 'n':
listPosN[numN].pos = (short)i;
numN++;
break;
case 'G':
case 'g':
listPosG[numG].pos = (short)i;
numG++;
break;
}
} for (int i = ; i < numB; i++)
{
for (int j = ; j < numI; j++)
{
if (listPosB[i].pos < listPosI[j].pos)
{
listPosB[i].next = j;
break;
}
}
} for (int i = ; i < numI; i++)
{
for (int j = ; j < numN; j++)
{
if (listPosI[i].pos < listPosN[j].pos)
{
listPosI[i].next = j;
break;
}
}
} for (int i = ; i < numN; i++)
{
for (int j = ; j < numG; j++)
{
if (listPosN[i].pos < listPosG[j].pos)
{
listPosN[i].next = j;
break;
}
}
} int count = ;
for (int b = ; b < numB; b++)
{
for (int i = listPosB[b].next; i < numI; i++)
{
for (int n = listPosI[i].next; n < numN; n++)
{
for (int g = listPosN[n].next; g < numG; g++)
{
count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
} /*
short startB;
short startI;
short startN;
short startG;
for (int b = 0; b < numB; b++)
{
startB = listPosB[b].pos; for (int i = 0; i < numI; i++)
{
startI = listPosI[i].pos;
if (startI < startB)
{
continue;
} for (int n = 0; n < numN; n++)
{
startN = listPosN[n].pos;
if (startN < startI)
{
continue;
} for (int g = 0; g < numG; g++)
{
startG = listPosG[g].pos;
if (startG < startN)
{
continue;
} count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
}
*/ free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}
第三版优化,还是运行时间超过3s,我是真没辙了.
#include <cstring>
#include <cstdio>
#include <assert.h> #define BING_MAX 1000000007 struct U2
{
short pos;
short next;
}; int Bing(const char* szBing, int len)
{
if (!szBing || !szBing[])
{
return ;
} U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
if (szBing[i] == 'b')
{
listPosB[numB].pos = (short)i;
numB++;
}
else if (szBing[i] == 'i')
{
listPosI[numI].pos = (short)i;
numI++;
}
else if (szBing[i] == 'n')
{
listPosN[numN].pos = (short)i;
numN++;
}
else
{
listPosG[numG].pos = (short)i;
numG++;
}
} int t = ;
for (int i = ; i < numB; i++)
{
for (int j = t; j < numI; j++)
{
if (listPosB[i].pos < listPosI[j].pos)
{
listPosB[i].next = t = j;
break;
}
}
} t = ;
for (int i = ; i < numI; i++)
{
for (int j = t; j < numN; j++)
{
if (listPosI[i].pos < listPosN[j].pos)
{
listPosI[i].next = t = j;
break;
}
}
} t = ;
for (int i = ; i < numN; i++)
{
for (int j = t; j < numG; j++)
{
if (listPosN[i].pos < listPosG[j].pos)
{
listPosN[i].next = t = j;
break;
}
}
} int count = ;
for (int b = ; b < numB; b++)
{
for (int i = listPosB[b].next; i < numI; i++)
{
for (int n = listPosI[i].next; n < numN; n++)
{
count += numG - listPosN[n].next;
}
} if (count > BING_MAX)
{
count -= BING_MAX;
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}
第四版代码:
#include <cstring>
#include <cstdio> #define BING_MAX 1000000007 struct U2
{
int pos;
int count;
}; int Bing(const char* szBing, int len)
{
if (!szBing || !szBing[])
{
return ;
} U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
if (szBing[i] == 'b')
{
listPosB[numB].pos = i;
numB++;
}
else if (szBing[i] == 'i')
{
listPosI[numI].pos = i;
numI++;
}
else if (szBing[i] == 'n')
{
listPosN[numN].pos = i;
numN++;
}
else if (szBing[i] == 'g')
{
listPosG[numG].pos = i;
numG++;
}
} int b = ;
int i = ;
int n = ;
int g = ;
int t; // 每个N之后有多少个G的选择
for (n = ; n < numN; n++)
{
while (listPosG[g].pos < listPosN[n].pos && g < numG)
{
g++;
}
listPosN[n].count = numG - g;
} // 每个I之后有多少个NG的选择
n = ;
for (i = ; i < numI; i++)
{
while (listPosN[n].pos < listPosI[i].pos && n < numN)
{
n++;
}
listPosI[i].count = ;
for (t = n; t < numN; t++)
{
listPosI[i].count += listPosN[t].count;
}
} // 每个B之后有多少个ING的选择
i = ;
int count = ;
for (int b = ; b < numB; b++)
{
while (listPosI[i].pos < listPosB[b].pos && i < numI)
{
i++;
}
listPosB[b].count = ;
for (t = i; t < numI; t++)
{
listPosB[b].count += listPosI[t].count;
} count += listPosB[b].count;
if (count > BING_MAX)
{
count -= BING_MAX;
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}
终于想到正确答案了,原来我一开始就误入歧途了,最早的代码算法复杂度是O(n^4),我将其优化到O(n^2),然后又优化到O(n*log(n)),而最终代码的复杂度是O(n).
#define BING_MAX 1000000007 int Bing(const char* szBing)
{
int numB = ;
int numI = ;
int numN = ;
int numG = ;
int pos = ;
while (szBing[pos])
{
if (szBing[pos] == 'b')
{
numB++;
}
else if (szBing[pos] == 'i')
{
numI += numB;
}
else if (szBing[pos] == 'n')
{
numN += numI;
}
else if (szBing[pos] == 'g')
{
numG += numN;
if (numG > BING_MAX)
{
numG -= BING_MAX;
}
}
pos++;
} return numG;
}
给定任意字符串,计算一共能组合成多少个单词bing的更多相关文章
- 给定任意一个字符串,使用 for in 语句来统计字符出现的个数
//找出字符串中的数字 var str = 'haj123sdk54hask33dkhalsd879'; /*function findNum(str){ var arr = []; var tmp ...
- 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...
- 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串
import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...
- 编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成
编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成.“组合 ”的规则如下: 1). str中的每个字母要么来自于part1,要么来自于part2 ...
- 给定一个字符串,仅由a,b,c 3种小写字母组成。
package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...
- Oracle中如何判断字符串是否全为数字,以及从任意字符串中提取数字
本文介绍了判断字符串是否全为数字的4种办法,另外还介绍了一个translate函数的小技巧,从任意字符串中提取数字(调用2次translate函数).这个办法是一个公司同事发现的,用起来很方便,但理解 ...
- JS求任意字符串中出现最多的字符以及出现的次数
我爱撸码,撸码使我感到快乐!大家好,我是Counter本节讲讲如何利用JS来查找任意给定的字符串,求字符串中出现次数最多的字符,出现的次数.直接上代码了,该注释的都注释啦.非常轻松加愉快.效果如下: ...
- 将一个字符串中的空格替换成“%20”(C、Python)
将一个字符串中的空格替换成“%20” C语言: /* ----------------------------------- 通过函数调用,传地址来操作字符串 1.先计算出替换后的字符串的长度 2.从 ...
- delphi string.split 按照任意字符串分割语句
delphi string.split 按照任意字符串分割语句 1.就是把一个指定的字符串用指定的分割符号分割成多个子串,放入一个 TStringList 中 function ExtractStri ...
随机推荐
- mysql的第一个程序
每次写java链接数据怎么写,这一次做一个总结,方便参考. 1.在mysql上下载mysql驱动jar包 2.下载的驱动包 3.程序目录 4.程序 package mysqlTest; import ...
- 再议js的传递和深复制
病理 基本类型的传递就是按值传递,比如说 var a = 1; var b = a; b = 3; console.log(a,b);//1,3 很明显,a的值并未因为b的值改变而变化,这是因为a只是 ...
- 个人博客www.0x002.com
cnblogs只是相当于一个备份,感兴趣的读者赏脸关注下.
- .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能
一.前言 ASP.NET Core本身已经集成了一个轻量级的IOC容器,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可,常见方 ...
- Framework类库(FCL)简介
Framework类库(Framework Class Library,FCL)是一组DLL程序集的统称,其中含有数千个类型定义,每个类型都公开了一些功能 部分常规的FCL命名空间 命名空间 内容说明 ...
- C#语法文本字面量
C#语法文本字面量 在日常生活中,文本用来表示除了数字以外的内容.例如有一个叫“比尔”的人,他的职位为“科长”.那么,“比尔”和“科长”都可以称为文本.在计算机里,现实世界中的文本通常被称为字符和字符 ...
- python 全排列
itertools模块现成的全排列: for i in itertools.permutations('abcd',4): print ''.join(i) 相关全排列算法: def perm(l): ...
- 模型构建<3>:交叉验证
交叉验证是模型比较选择的一种常用方法,本文对此进行总结梳理. 1.交叉验证的基本思想 交叉验证(cross validation)的基本思想就是重复地利用同一份数据. 2.交叉验证的作用 1)通过划分 ...
- JQ中get()与eq()的区别
.eq() : 减少匹配元素的集合,根据index索引值,精确指定索引对象. .get() : 通过检索匹配jQuery对象得到对应的DOM元素. 同样是返回元素,那么eq与get有什么区别呢? eq ...
- Java Threads 多线程10分钟参考手册
1 同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通常把这 ...