给定任意字符串,计算一共能组合成多少个单词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 ...
随机推荐
- 调整linux系统时区
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 好吧,使用tzselect又靠谱些,使用前把/etc/localtime删除了. 执行上 ...
- libhiredis.so.0.13: cannot open shared object file: No such file or director
Hiredis安装步骤: tar zxvf antirez-hiredis-v0.10.1-0-g3cc6a7f.zip cd antirez-hiredis-3cc6a7f make 解决办法: m ...
- 1006 Sign In and Sign Out (25)(25 point(s))
problem At the beginning of every day, the first person who signs in the computer room will unlock t ...
- django设置数据库事务,通过异常处理回滚事务
1.setting.py配置文件,开启事务ATOMIC_REQUESTS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql' ...
- 浏览器在线查看pdf文件 pdf.js的使用教程
谷歌浏览器可以直接在线查看pdf,而IE内核浏览器无法在线查看,默认是下载. 这里用到的是pdf.js,不仅支持IE内核浏览器,而且兼容手机查看pdf 官网地址:http://mozilla.gith ...
- chinese hacker-----WriteUp
原题地址:http://ctf5.shiyanbar.com/web/2/ 提示下载一个数据库 下载下来后发现是加密的 有密码,但发现密码不是4648 这里用到“DbView” 直接破解密码进入 发 ...
- JavaEE-学习目录
JavaEE ============================================ Web工作机制 JSP Struts基础 Struts核心文件 Struts数据校验与国际化 S ...
- ESB的几个基本概念
京-星之泪: 请教一个问题:esb中路由和管道对的概念应该怎么理解,各自有什么用途,他们之间的关系 北京-kimmking: transport endpoint inbound outboun ...
- 在IIS上部署基于django WEB框架的python网站应用
django是一款基于python语言的WEB开源框架,本文给出了如何将基于django写的python网站部署到window的IIS上. 笔者的运行环境: Window xp sp3 IIS 5.1 ...
- java的(PO,VO,TO,BO,DAO,POJO)解释1
java的(PO,VO,TO,BO,DAO,POJO)解释 O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定 ...