55. 2种方法求字符串的组合[string combination]
【本文链接】
http://www.cnblogs.com/hellogiser/p/string-combination.html
【题目】
题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
【分析】
在之前的博文28.字符串的排列[StringPermutation]中讨论了如何用递归的思路求字符串的排列。同样,本题也可以用递归的思路来求字符串的组合。
【递归法求组合】
可以考虑求长度为n的字符串中m个字符的组合,设为C(n,m)。原问题的解即为C(n, 1), C(n, 2),...C(n, n)的总和。对于求C(n, m),从第一个字符开始扫描,每个字符有两种情况,要么被选中,要么不被选中。如果被选中,递归求解C(n-1, m-1);如果未被选中,递归求解C(n-1, m)。不管哪种方式,n的值都会减少,递归的终止条件n=0或m=0。
【代码】
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
// 55_StringCombination.cpp : Defines the entry point for the console application.
// /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/5/24 */ #include "stdafx.h" // print string combination for (; iterBegin != iterEnd; ++ iterBegin) // get string combination recursively // base cases // (2) not choose current char // string combination void test_base(char *str) void test_case1() void test_case2() void test_case3() void test_main() int _tmain(int argc, _TCHAR *argv[]) |
由于组合可以是1个字符的组合,2个字符的组合……一直到n个字符的组合,因此在函数void StringCombination(char *str)中,需要一个for循环。另外,用一个vector来存放选择放进组合里的字符。
【位运算求组合】
另外本题还有一个巧妙的思路,可以从位运算出发求组合。用一个二进制数字,来决定字符的取舍,某一位为1,则取对应的字符,若为0则不取,就能够实现字符组合。
例如对于“abc”,长度为3,则共有7种组合可能。让num 从1自增到7,跟字符的每一位进行判断,是否取舍。
比如:num=1,即001时:
(1)j指向第1个字符,(a>>j)&1==1,则取a;
(2)j指向第2个字符,(a>>j)&1==0,则舍弃b;
(3)j指向第3个字符,(a>>j)&1==0,则舍弃c;
此次组合的字符串为a;
以此类推。
当num=7,即111时:
(1)j指向第1个字符,(a>>j)&1==1,则取a;
(2)j指向第2个字符,(a>>j)&1==1,则取b;
(3)j指向第3个字符,(a>>j)&1==1,则取c;
此次组合的字符串为abc;
那么当num依次取完所有的值,就可以得到所有的字符串组合。
【代码】
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/5/24 */ void StringCombinationUsingBitwise(char *str) { // use bitwise operations to get string combination if(NULL == str || *str == '\0') return; int len = strlen(str); ) return; << len; ; i < sum; ++i) { ; j < len; j++) { if ((i >> j) & 0x1) { // choose char at str[j] printf("%c", str[j]); } } printf("\n"); } } |
相对于 【递归法求组合】,【位运算求组合】速度更快,其时间复杂度为T=n*2n,但是n不能超过32.
【注意】
多谢“路上的脚印”的提醒,该算法只能适用于字符串中字符都不相同的情形。如果有相同字符,则不再适合,需要进一步修正。
【参考】
http://zhedahht.blog.163.com/blog/static/2541117420114172812217/
http://zhuyanfeng.com/archives/3246
http://blog.csdn.net/hackbuteer1/article/details/7462447
http://blog.csdn.net/wuzhekai1985/article/details/6643127
【本文链接】
http://www.cnblogs.com/hellogiser/p/string-combination.html
55. 2种方法求字符串的组合[string combination]的更多相关文章
- JS四种方法去除字符串最后的逗号
<script> window.onload=function() { var obj = {name: "xxx", age: 30, sex: "fema ...
- 实验04——java保留小数的两种方法、字符串转数值
package cn.tedu.demo; import java.text.DecimalFormat; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ ...
- Java经典案例之用三种方法求1~100以内素数之和
素数,不能被除了1和本身以外整除的数被称为素数.接下来我用三种方式求得1~100以内素数. 方式一 外层每循环一次,内层就计算出这个数有几个因子,我们都知道素数的因子只有两个,所以如果个数为2就加进总 ...
- 求逆元的两种方法+求逆元的O(n)递推算法
到国庆假期都是复习阶段..所以把一些东西整理重温一下. gcd(a,p)=1,ax≡1(%p),则x为a的逆元.注意前提:gcd(a,p)=1; 方法一:拓展欧几里得 gcd(a,p)=1,ax≡1( ...
- LIS(两种方法求最长上升子序列)
首先得明白一个概念:子序列不一定是连续的,可以是断开的. 有两种写法: 一.动态规划写法 复杂度:O(n^2) 代码: #include <iostream> #include <q ...
- 四种方法求Capacitated Facility Location Problem问题
问题详情 1. 贪心算法 1.1 算法框架 此题可以利用贪心算法来求解, 可以假设只关注顾客的cost, 当仓库满了就在下一个仓库里 具体解决方案: 将每个顾客到工厂的cost 由小到大进行排序 从第 ...
- Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次
[请尊重原创版权,如需引用,请注明来源及地址] > 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现 ...
- php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)
php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...
- python字符串转换成变量的几种方法
个人比较喜欢用第三种方法 var = "This is a string" varName = 'var' s= locals()[varName] s2=vars()[varNa ...
随机推荐
- 【C#】菜单功能,将剪贴板JSON内容或者xml内容直接粘贴为类
VS 2015菜单功能,将剪贴板JSON内容或者xml内容直接粘贴为类
- Spring在非web应用中关闭IoC容器 (registerShutdownHook)
在基于web的ApplicationContext实现中,已有相应的实现来处理关闭web应用时恰当地关闭Spring IoC容器.但,如果你正在一个非web应用的环境下使用Spring的IoC容器,如 ...
- 基于bootstrap样式的tree,
<!doctype html><html lang="zh"><head> <meta charset="UTF-8" ...
- jQuery 事件方法
事件方法触发器或添加一个函数到被选元素的事件处理程序. 下面的表格列出了所有用于处理事件的 jQuery 方法. 方法 描述 bind() 向匹配元素附加一个或更多事件处理器 blur() 触发.或将 ...
- Android 轮换页面+TabHost 实例
最终效果展示: 首先我们需要一个ViewPager控件,不过可以发现在左侧的控件列表中并没有这个控件 这时我们要去升级包中查看 然后在厘米找到 ViewPager.class 这时我们双击这个发现不能 ...
- 懒加载(getter\setter理解)
为什么要用懒加载 1.首先看一下程序启动过程:(如图) 会有一个mian的设置,程序一启动会加载main.storyboard main.storyboard又会加载箭头所指的控制器 控制器一旦加载, ...
- UVA 11235Frequent values(RMQ)
训练指南P198 题意:给出一个非降序排列的整数数组a1, a2…… an,你的任务是对于一系列询问(i,j),回答ai, ai+1 ……aj 中出现的次数最多的次数 这题不仅学到了rmq的应用还学到 ...
- iframe自适应高度
http://wenrunchang123.iteye.com/blog/1684843
- sql server中对xml进行操作
一.前言 SQL Server 2005 引入了一种称为 XML 的本机数据类型.用户可以创建这样的表,它在关系列之外还有一个或多个 XML 类型的列:此外,还允许带有变量和参数.为了更好地支持 XM ...
- web前端基础知识-(五)jQuery
通过之前的学习我们已经了解了html.css.javascript的相关知识:本次我们就共同学习进阶知识:jQuery~ 一.什么是jQuery? jQuery其实就是一个轻量级的javascript ...