文章来源: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. Yii2 GridView自定义链接之重写 ActionColumn

    最近刚开始用yii2,真是超棒的,但是也有许多不足的地方,今天要说的就是GridView链接问题.   <?= GridView::widget([ 'dataProvider' => $ ...

  2. Hello WPF!

    WPF是微软提供的用户界面框架,它提供了统一的编程模型.语言,实现了分离界面设计人员与开发人员的工作.相对基于C++的MFC来说,界面更加美观,操作更加便捷,是新WIN环境下UI的首选. vs中新建W ...

  3. 让所有浏览器包括IE6即支持最大宽度又支持最小宽度。

    让所有浏览器包括IE6即支持最大宽度又支持最小宽度. _height  _width:针对ie6 css hack .yangshi{max-width:620px;min-width:1px;_wi ...

  4. Openstack学习历程_1_视频

    学习视频:讲解Openstack每个模块对应的作用

  5. Open vSwitch简述

    一.基础术语 1.Packet (数据包):网络转发的最小数据单元,每个包都来自某个端口,最终会被发往一个或多个目标端口,转发数据包的过程就是网络的唯一功能. 2.Bridge (网桥):Open v ...

  6. java 的复用工具 - jar包

    前言 Java提供了jar包的机制,使得已经开发好了的类能够顺利的被将来的工程所复用. 本章主要讲解如何使用这种工具. 包的作用 包能够将不同功用的类组织起来,从而确保类名的唯一性. 为了保证包名的唯 ...

  7. iOS7中如何去除UINavigationbar下边的那条黑线

    做项目过程中遇到要去掉导航栏下面的一条黑线,从网上找到的一个方法 默认UINavigationbar样式 准备用于替换的背景 替换后的效果 if ([self.navigationController ...

  8. abap append 用法

    [转自http://blog.chinaunix.net/uid-7982817-id-91999.html]Append用法总结 2008-11-14 11:42:19 分类: Syntax APP ...

  9. urlscan使用详解

    0x01 简介与下载  URLScan是集成在IIS上的,可以制约的HTTP请求的安全工具.通过阻止特定的HTTP请求,URLScan安全工具有助于防止潜在的有害的请求到达服务器上的应用. 最新版UR ...

  10. Codeforces Round #134 (Div. 2)

    A. Mountain Scenery 枚举山顶位置,满足\(r_{i-1} \lt r_i - 1 \gt r_{i+1}\). 范围要开\(2N\). B. Airport 优先队列维护最值. C ...