文章来源:http://blog.csdn.net/aa512690069/article/details/17918799

其原文是微软一个小题目:http://hero.csdn.net/Question/Details?ID=215&ExamID=210

本届大赛由微软必应词典冠名,必应词典(http://cn.bing.com/dict/?form=BDVSP4&mkt=zh-CN&setlang=ZH)是微软推出的新一代英语学习引擎,里面收录了很多我们常见的单词。但现实生活中,我们也经常能看到一些毫无规则的字符串,导致词典无法正常收录,不过,我们是否可以从无规则的字符串中提取出正规的单词呢?

例如有一个字符串"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取余数之后的结果。

******************************************************************************

我的思路(这个思路只是针对任何单词,前提是单词中没有重复的字母,比如说:good,o重复了则不适用,原因是加上重复字母的话得复杂不少而没有做):按照例子 “iinbinbing“ 来说,可以画出如下4张图,来对应bing的4种情况,其纵轴是该字符出现在字符串中的索引(1开始):

那么这个统计问题就转换成了线段从b开始连接到尾部g的线路数,且连接的点位置必须满足前一个字母位置小于后一个字母位置(顺序)。

如下图,bing的组成个数 n = b1 + b2。   n = 1 + 3 = 4;

有了这个想法,然后开始想办法统计连接到尾部的线路数加总即可.既然是统计到尾部的线路数,当然从尾部开始找。于是乎,得到如下统计图表:

有了这个想法,然后开始想办法统计连接到尾部的线路数加总即可.既然是统计到尾部的线路数,当然从尾部开始找。于是乎,得到如下统计图表:

那么,其实我们就是为了求总数,而不必要得到每一点的所有线路,所以。我们每一步执行都加总一次,即得到如下图:

那么,这个图的字母b的第一个计数器(b, 4)即为bing的组合个数。也就是连接到尾部的总个数。

结语:

这个实现的步骤复杂度为O(2N),计算长度 + 统计,2次循环。

可以看得出这里为什么不允许重复字母,如果是重复的字母则需要建立复合计数器(即一个字母有多个计数器,分别对不同位置进行计数),但是鉴于题目没有这些要求而没有做多余的事情。

后来发现,其实这里正着循环也行,复杂度O(N),长度不需要计算。

实现代码如下(这个是我提交给微软考试用的题目,也就不改了):

 #include<stdio.h>
#include<malloc.h>
int howmany (const char* s)
{
unsigned int len = ;
const char* e = s;
const char* key = "bing";
const char* ke = key;
unsigned int keyLen = ;
long long num = ;
long long* bing = ;
int idx[] = {};
unsigned int i = ; if(s == || *s == ) return ; while(*ke++ != );
while(*++e != );
keyLen = ke - key - ; bing = (long long*)malloc(sizeof(long long) * keyLen);
for(i = ; i < keyLen; ++i)
{
idx[key[i]] = i + ;
bing[i] = ;
} for (--e; e >= s; --e)
{
int n = idx[*(unsigned char*)e]; if(!n)
continue; if(n == keyLen)
{
bing[n - ]++;
}
else
{
if(bing[n] > )
bing[n - ] += bing[n];
}
} num = bing[];
free(bing);
return num % ;
}

复杂度O(N)

 int howmany(const char* str)
{
long long counter[] = {};
if(str == ) return ; for(; *str != ; str++)
{
switch(*str)
{
case 'b': counter[]++; break;
case 'i': counter[]+=counter[]; break;
case 'n': counter[]+=counter[]; break;
case 'g': counter[]+=counter[]; break;
}
}
return counter[] % ;
}

*************************************************

以上都是原作者的分析和代码。个人感觉前面的分析没讲清楚,不过最后一段代码倒是很好。我自己写,原先想的简单,直接没考虑b、i、n、g几个字母的顺序问题,直接统计个数然后相乘(我想的太简单了⊙﹏⊙b汗)。

看了作者分析,知道要考虑顺序问题,然后再看最后一段代码,想想理解了。谢谢作者。

bing统计【转自CSDN博客】的更多相关文章

  1. CSDN博客添加量子恒道统计代码步骤

    CSDN博客添加量子恒道统计代码步骤. 1. 去量子恒道网站统计 注册账户: 2. 添加已有的CSDN博客地址: 3. 添加博客后恒道代码里面会给你一个JavaScript脚本,记下里面的一串数字: ...

  2. 怎样为你的CSDN博客增加百度统计

    曾经CSDN使用的 量子统计 能够非常好的统计我们的博客的訪问数量.地域等等信息,可是不知道后来为什么不在使用了.那么怎样找到 一种替换的方式那? 下边,就给大家介绍一下怎样使用百度统计. 百度统计账 ...

  3. 为你的CSDN博客添加CNZZ流量统计功能

    一.流量统计介绍 流量统计是指通过各种科学的方式,准确的纪录来访某一页面的访问者的流量信息,目前而言,必须具备可以统计. 1.简介 统计独立的访问者数量(独立用户.独立访客): 可以统计独立的IP地址 ...

  4. CSDN博客怎样加入量子恒道统计?

    CSDN博客申请专家通过后,能够加入量子恒道统计,这样就能够查看更加具体的訪问统计信息,而不不过一个訪问次数.达到专家级别了可能都是电脑高手了.这里班门弄斧了. 登录博客进入个人中心首页,点击管理博客 ...

  5. 在CSDN博客中添加量子恒道统计功能的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 什么是量子恒道统计?量子恒道统计是一套免费的网站流量统计分析系统.致力于为所有个人站长.个人博主.所有网站管理者.第三 ...

  6. Python爬取CSDN博客文章

    0 url :http://blog.csdn.net/youyou1543724847/article/details/52818339Redis一点基础的东西目录 1.基础底层数据结构 2.win ...

  7. Python 爬取CSDN博客频道

    初次接触python,写的很简单,开发工具PyCharm,python 3.4很方便 python 部分模块安装时需要其他的附属模块之类的,可以先 pip install wheel 然后可以直接下载 ...

  8. Python爬虫小实践:爬取任意CSDN博客所有文章的文字内容(或可改写为保存其他的元素),间接增加博客访问量

    Python并不是我的主业,当初学Python主要是为了学爬虫,以为自己觉得能够从网上爬东西是一件非常神奇又是一件非常有用的事情,因为我们可以获取一些方面的数据或者其他的东西,反正各有用处. 这两天闲 ...

  9. 神一样的CSDN博客排名规则

    本文转载于:http://blog.csdn.net/littletigerat/article/details/17448521 神一样的CSDN博客排名规则 一.引言 年. 马年CSDN博客,毫无 ...

  10. 梦想还是要有的-纪念正式成为csdn博客专家暨年中总结

    csdn博客:http://blog.csdn.net/tuzongxun 我的csdn历程(坚持总会有收获):   一年零三个月之前,2015年3月3日,我在csdn写下第一篇技术博客,只是记录了一 ...

随机推荐

  1. 查询某个表或者所有表的字段说明 SQLServer

    查询某个表或者所有表的字段说明SELECT    [Table Name] = OBJECT_NAME(c.object_id),    [Column Name] = c.name,    [Des ...

  2. 【Zhejiang University PATest】02-3. 求前缀表达式的值

    算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4.请设计程序计算 ...

  3. AngularJS基本指令

    <!doctype html> <html  ng-app> <head>   <meta charset="UTF-8">   & ...

  4. 程序员是怎么炼成的---OC题集--练习答案与题目(3)

    1.init 2.initWithBytes:length:encoding: 3.initWithCharacters:length: 4.initWithCString:encoding: 5.i ...

  5. HDU5534--Partial Tree (完全背包)

    点击打开链接 思路:总度数为2n-2,由于每个节点都至少要有1个度,所以可以看做把剩余n-2个点放入n个节点的背包问题.dp[i]表示放入i个度后的最大值 #include<cstdio> ...

  6. C#基础指针类型

    在C#的不安全的代码书写中,类型可以是指针类型.值类型或引用类型. 指针类型声明具有下列形式之一:   type* identifier; void* identifier; //allowed bu ...

  7. myEclipse使用有感

    一.破解 使用myeclipse 10.0版本:然后破解:(之前我使用10.7破解成功了,但是发布有问题) 二.发布注意事项 1.清理发布目录, 不要有多个项目搅和 2.js相关, 注意清理浏览器缓存 ...

  8. Magento模板Paypal付款不成功返回清空购物车产品【解决方案】

    Magento模板Paypal付款不成功返回清空购物车产品[解决方案] 今天我有个客户要集成l了paypal账户但在使用是遇到了问题遇到了这个问题. 当我们使用第三方支付工具Gateway如paypa ...

  9. LeetCode Median of Two Sorted Arrays 找中位数(技巧)

    题意: 给两个有序(升or降)的数组,求两个数组合并之后的中位数. 思路: 按照找第k大的思想,很巧妙.将问题的规模降低,对于每个子问题,k的规模至少减半. 考虑其中一个子问题,在两个有序数组中找第k ...

  10. poj 2299 树状数组求逆序对数+离散化

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 54883   Accepted: 20184 ...