c++输出字符串组合。
这是一个很常见的面试题,我来详细讲解算法。
首先假设有 ABCDEF这6个字符的字符串S,现在要找出3个字符的所有组合;
思路如下:
首先我们找到这个字符组合中一定包含A字符的组合,那么A字符肯定就定下来了,即包含S中第一个字符的组合,然后以剩下的字符串BCDEF作为新的字符串,找出所有的2个字符的组合,那就得到了A包含的所有组合了是吧。。
然后我们就可以省去A了,因为包含A的所有的组合都找到了,所以我们又开始以BCDEF这个字符串找出所有的3个字符的组合;
那么做法和上面一样,又以第一个为指定的字符,CDEF进行找出所有2个字符的组合。这样包含B开头的所有字符组合也找完了吧‘
依次遍历下去,达到E的时候,不能再进行了,因为剩余长度小于3个了。
以上就是我们的方法;
当然找2个字符组合的也是利用上面的方法递归进行。
那么就这样就OK了;
我们的伪代码写出来就很方便了:
for(ch:S && len(S)>=n)///ch为S遍历到的字符, len(S)>=n表示剩下的字符串长度要大于我们的字符组合的长度。
Combine[ S, n]= Combine[S+1,n-1] * ch //这里的乘号表示的是当前ch与后面找到的组合所一起构成的组合。
combine[S,n]表示我们在S的字符串中找出所有n个字符的组合。
相信大家看得差不多,来真实的代码:
#include<stdio.h> #include<string.h>
void combine(char *source,char *result,int n) { int len=strlen(source); if(n==0)//找到n个的时候,输出结果 { printf(“%s\n”,result); } else { int i; int j; for(j=0;*(result+j)!=’\0′;j++);//j目的是为了当前第n轮的字符插入到result的末尾,即算出末尾的那个位置
for(i=0;i<len-n+1;i++)//在第n轮处开始往后依次遍历,不能超出len-n+1,
比如6个字符,现在找3长的组合,
第2轮最终只能在第5个字符处,因为第3轮最后的位置肯定为第六个字符。 { *(result+j)=*source;//设置result *(result+j+1)=’\0′; //为result的下一个设置结束符合,否则下一轮的j会有错; source++; //为这一轮的起始位置往后移动一个位置。 combine(source,result,n-1); //以下一个位置作为N-1轮的起始位置。 }
}
} int main()
{ int const n = 3; const char * const source = “ABCDE”; char result[4] = {‘\0′}; if(n>0 && strlen(source)>0 && n<=strlen(source)) combine(source, result, 3); return 0;
}
得到的结果为:
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE