原题叙述:http://www.iteye.com/topic/15295
引用
假设有这样一种字符串,它们的长度不大于 26 ,而且若一个这样的字符串其长度为 m ,则这个字符串必定由 a, b, c ... z 中的前 m 个字母构成,同时我们保证每个字母出现且仅出现一次。比方说某个字符串长度为 5 ,那么它一定是由 a, b, c, d, e 这 5 个字母构成,不会多一个也不会少一个。嗯嗯,这样一来,一旦长度确定,这个字符串中有哪些字母也就确定了,唯一的区别就是这些字母的前后顺序而已。
现在我们用一个由大写字母 A 和 B 构成的序列来描述这类字符串里各个字母的前后顺序:
如果字母 b 在字母 a 的后面,那么序列的第一个字母就是 A (After),否则序列的第一个字母就是 B (Before);
如果字母 c 在字母 b 的后面,那么序列的第二个字母就是 A ,否则就是 B;
如果字母 d 在字母 c 的后面,那么 …… 不用多说了吧?直到这个字符串的结束。
这规则甚是简单,不过有个问题就是同一个 AB 序列,可能有多个字符串都与之相符,比方说序列“ABA”,就有“acdb”、“cadb”等等好几种可能性。说的专业一点,这一个序列实际上对应了一个字符串集合。那么现在问题来了:给你一个这样的 AB 序列,问你究竟有多少个不同的字符串能够与之相符?或者说这个序列对应的字符串集合有多大?注意,只要求个数,不要求枚举所有的字符串。
这个结构很有意思。给定一个字符串的集合,求把新的字母插入到最后一个字母之前或之后,生成的新的字符串集合。
直观的想法会是从头模拟,对于集合里面每个字符串,试着把新字母往里插,一个字符串能插出0到n个结果,n是字符串的长度。然后把每个字符串插出来的结果合并。但是,这个集合明显是指数式爆炸增长的阿。这样穷举显然是不行的。
穷举每一个元素不行,那就想想,集合是不是可以分成多个子集,每个子集的处理方式都是相同的?
很容易观察到,新字母的插入位置,只和最后一个字母相关。比如要把z插入由a-y组成的字符串里,我们只要关心y所在的位置就可以了。不管其他字母如何排列,我们都能用同样的方式插。
更好的想法是反过来想:
比如我们要把z插在字符串第9个位置,放置在y之后(After),
那么,“我把z插在第9个位置”这句话,就可以分解成如下几种情况:
“原来y在第0个位置,我把z插在第九个位置”
“原来y在第1个位置,我把z插在第九个位置”
“原来y在第2个位置,我把z插在第九个位置”
“原来y在第3个位置,我把z插在第九个位置”
“原来y在第4个位置,我把z插在第九个位置”
“原来y在第5个位置,我把z插在第九个位置”
“原来y在第6个位置,我把z插在第九个位置”
“原来y在第7个位置,我把z插在第九个位置”
“原来y在第8个位置,我把z插在第九个位置”
然后,我们再问自己:
原来的集合里,有多少个字符串满足“原来y在第0个位置”?经计算,有k[0]个
原来的集合里,有多少个字符串满足“原来y在第1个位置”?经计算,有k[1]个
原来的集合里,有多少个字符串满足“原来y在第2个位置”?经计算,有k[2]个
原来的集合里,有多少个字符串满足“原来y在第3个位置”?经计算,有k[3]个
...
原来的集合里,有多少个字符串满足“原来y在第7个位置”?经计算,有k[7]个
原来的集合里,有多少个字符串满足“原来y在第8个位置”?经计算,有k[8]个
最后,我们问自己:
新的集合中,有多少个字符串满足“现在的z在第9个位置”?
计算的方法就是把k[0],k[1],k[2]一直到k[8]全部加起来。
如果你要把z放到第9位置,但是要插到y的前面(Before),那就算算:
“原来y在第9个位置,我把z插在第九个位置”(原来y在第9个,插入z之后,y被挤到第10个了)
“原来y在第10个位置,我把z插在第九个位置”
“原来y在第11个位置,我把z插在第九个位置”
。。。
“原来y在第24个位置,我把z插在第九个位置”
然后加起来。
如果你把z能插的位置都算一遍,然后再加起来,就是结果了。但是,我们的中间步骤需要保留这个“集合中,有多少字符串,z在第n个位置”(for n in 0..25)
算法就出来了:
保留一个数组:第i个元素储存“集合里有多少字符串满足‘最后一个字母在第i个位置’”。
显然初始值是[1]。只有一个元素,就是1。因为集合是{"a"},a只能在第0个位置,且只有1种情况。
当读到一个字符(A或B),如果是A,就生成一个新的数组,第i个元素是旧数组第0,1,...,i-1个元素的数值的和。如果是B,就是i,i+1,...,n-1个元素之和。n是原数组的大小。
读完最后一个字母,算完,将新数组元素加起来,就是结果。
时间复杂度:O(n^3)。一共n个字母,数组长度随字母个数线性增长。每一个字母都是n^2的,n是数组长度。因为要对每个新数组的元素,遍历一遍旧数组。
空间复杂度:O(n)。可以用两个数组轮流使用。Haskell和Java都有垃圾回收,不用太在意。
实现:
module Main where
main = do
ln <- getLine
putStrLn $ show $ afterBefore $ ln
afterBefore :: [Char] -> Integer
afterBefore = sum . foldl induct [1]
induct :: [Integer] -> Char -> [Integer]
induct spectrum place = case place of
'A' -> [sum (take n spectrum) | n <- [0..(length spectrum)]]
'B' -> [sum (drop n spectrum) | n <- [0..(length spectrum)]]
分享到:
相关推荐
微信小程序 首字母排序选择 (源码)微信小程序 首字母排序选择 (源码)微信小程序 首字母排序选择 (源码)微信小程序 首字母排序选择 (源码)微信小程序 首字母排序选择 (源码)微信小程序 首字母排序选择 (源码)微信小...
"首字母排序选择"这个主题可能是指在微信小程序中实现的一种功能,即对数据进行首字母排序,以便用户可以更高效地查找和浏览信息。这在处理大量条目时尤其有用,例如在联系人列表、商品目录或任何需要分类检索的数据...
微信小程序源码 首字母排序选择(学习版)微信小程序源码 首字母排序选择(学习版)微信小程序源码 首字母排序选择(学习版)微信小程序源码 首字母排序选择(学习版)微信小程序源码 首字母排序选择(学习版)微信小程序源码 ...
在易语言中,我们通常会用到字符串处理函数来处理字母排序的问题。 对于英文字母排序,我们需要知道ASCII码的概念。在计算机中,每个字符都有一个对应的ASCII码,英文小写字母的ASCII码从97('a')到122('z'),...
5. **数据结构**:为了实现按字母排序,开发者可能使用了已排序的城市名列表,或者在加载数据时就进行排序处理。 6. **点击事件监听**:右侧字母栏和列表项的点击事件需要监听器(OnClickListener或OnTouchListener...
微信小程序——首字母排序选择(截图+源码).zip 微信小程序——首字母排序选择(截图+源码).zip 微信小程序——首字母排序选择(截图+源码).zip 微信小程序——首字母排序选择(截图+源码).zip 微信小程序——首...
全国主要城市列表, 包含市级以上城市, 按照字母排序, xml文件
在Android开发中,构建一个根据字母排序的城市列表是一项常见的任务,尤其在开发地图应用或信息检索类应用时。这个任务涉及到UI设计、数据处理以及排序算法等多个知识点。下面将详细阐述实现这一功能所需的关键技术...
本主题将深入探讨如何使用RecyclerView的ItemDecoration机制来实现字母排序效果,这一功能常见于联系人应用或者商店商品分类等场景。 首先,我们需要理解RecyclerView.ItemDecoration的作用。这个接口允许我们在...
本教程将深入讲解如何实现一个按字母排序的ListView,并提供快速定位到特定字母的功能。这一特性常见于通讯录应用,用户可以通过点击字母栏迅速跳转到以该字母开头的联系人。 首先,我们需要创建一个适配器...
在线中英文根据首字母排序工具: http://tools.jb51.net/aideddesign/zh_paixu 您可能感兴趣的文章:mysql的中文数据按拼音排序的2个方法mysql如何按照中文排序解决方案MySQL按照汉字的拼音排序简单实例
通过以上步骤,我们就可以实现一个类似微信联系人的按照字母排列的ListView。在SortPhoneDemo项目中,你可以找到具体实现的代码,包括Activity、Adapter、数据模型等类,通过对这些代码的学习和理解,你可以更好地...
标题“SQL按拼音首字母排序”以及描述中的关键词“SQL按拼音排序”,指向了一种特殊的数据排序需求:在数据库中,针对包含中文字符的字段,按照中文拼音的首字母进行排序。这在处理大量含有中文名称、地点等信息的...
小程序源码 首字母排序选择 (代码+截图)小程序源码 首字母排序选择 (代码+截图)小程序源码 首字母排序选择 (代码+截图)小程序源码 首字母排序选择 (代码+截图)小程序源码 首字母排序选择 (代码+截图)小程序源码 首...
这个压缩包文件“安卓A-Z字母排序索引相关-通讯录按首字母排列关键字查找.rar”可能包含了一系列示例代码或教程,用于帮助开发者理解和实现这一功能。下面将详细讲解通讯录按首字母排列以及关键字查找的相关知识点。...
`java中对单层json进行key字母排序`的标题指出了我们需要对一个单层JSONObject的键进行字母升序排序。描述提到这个资源可以直接在程序中使用,意味着提供了一个功能函数来实现这一操作。 在提供的代码中,可以看到...
本篇文章将详细讲解如何在Android中实现ListView的字母排序以及调整字母位置。 首先,我们需要理解字母排序的基本原理。通常,我们可以通过对数据源进行排序来实现这一目标。假设我们的数据源是一个包含字符串的...
在JavaScript编程中,对中文字符串进行按首字母排序是一个常见的需求,特别是在构建具有搜索和过滤功能的用户界面时。这个任务涉及到对汉字的处理,因为汉字不像英文字符那样可以直接进行字母顺序比较。以下是对该...
在微信小程序的开发中,实现首字母排序选择功能是一项常见的需求,这通常涉及到用户界面的友好性和数据管理的效率。这个压缩包“微信小程序-首字母排序选择功能开发.zip”包含了一个小程序模板代码,用于帮助开发者...
在IT行业中,字母排序是一个基础但重要的概念,尤其在编程和数据处理中有着广泛的应用。本文将深入探讨26英文字母排序的相关知识点,并结合Android平台进行讨论。 首先,我们来理解什么是字母排序。在计算机科学中...