请教一个较难面试题(穷举)

yangbo76 2008-03-12 10:51:43
输入一个字符串 :abcde
输出所有可能的排列组合: abced, dabce.....

当然如果是abccd,要考虑重复字母的问题。

谢谢各位大虾!
...全文
132 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangbo76 2008-03-13
  • 打赏
  • 举报
回复
next_permutation 确实好用,连重复排列都不用操心。

sort(str.begin(),str.end());
do {
if( foundInDictionary( str, dictfile ))
cout << str << endl;
} while( next_permutation ( str.begin(), str.end()));

jinwei1984 2008-03-12
  • 打赏
  • 举报
回复
将字符串的下标用去排序,直接用next_permutation

每次将排序后的下标对应位置的字符依次还原,构成一个字符串放到MAP里面,最后完了输出就可以了
qiucp 2008-03-12
  • 打赏
  • 举报
回复
#include <stdio.h>
const int N = 9;
int Hui(int* p, int num, int have);
int main(int argc, char* argv[])
{
int p[N];
int n;
printf("Input n(n<=9):");
scanf("%d", &n);
int r = Hui(p, n, 0);
printf("Total %d\n", r);
return 0;
}

// *p:数组;num:数组个数;have:已经装入数组的个数
int Hui(int* p, int num, int have)
{
int r = 0;
if (have == num)
{
for (int i = 0; i < num; i++)
{
printf("%d", p[i]);
}
printf("\n");
r = 1;
}
else
{
for (int i = 1; i <= num; i++)
{
bool b = false;
for (int j = 0; j < have; j++)
{
if (p[j] == i)
{
b = true;
break;
}
}
if (!b)
{
p[have] = i;
r += Hui(p, num, have + 1);
}
}
}
return r;
}
AmHuman 2008-03-12
  • 打赏
  • 举报
回复
排列组合用一般的循环很难出来的。
看过算法设计不?有说到排列组合,用的是递归。
对一串字符的排列定义为{a,b,c,d...}
取出其中一个如a,得到a{b,c,d},表示a加在排列{b,c,d},直到只剩一个{X}那就只有一种排列方式了。
就这个递归思想了。
重复字符的话你把排列出来的东西放到MAP里它自动就消去重复项了。
billy1985 2008-03-12
  • 打赏
  • 举报
回复
用递归的思想比较容易解决这个问题
p0303230 2008-03-12
  • 打赏
  • 举报
回复
上面代码是 几个元素的出栈情况

跟lz想要的不对
p0303230 2008-03-12
  • 打赏
  • 举报
回复

public class stackout{
private long fact(int n)
{
if(n == 0)
return 1;
return fact(n - 1)*n;
}
private final long M(final int n)
{
return (fact(2*n))/((n + 1)*fact(n)*fact(n));
}
private static char allchar[] = {'1','1', '2','3','4'};//'a'+7,'a','b'+7,'b','c'+7,'c',
//'d'+7,'d','e'+7,'e'};
private static final int N = allchar.length;
private char outchar[] = new char[N];
private boolean op[] = new boolean[2*N];
private int count = 0;
private String[] out_st = new String[(int) M(N)];
public void k(int all, int in, int out)
{
if(all > 0)
{
op[out] = true;
k(all - 1, in + 1, out + 1);
if(in > 0)
{
op[out] = false;
k(all, in - 1, out + 1);
}
}else{
out_st[count] = "";
boolean repeat = false;
int spos = 0;
int cpos = 0;
for(int i = out; i < 2*N; i++)
{
op[i] = false;
}
// 打印出栈顺序
for (int i=0; i< N*2; i++) {
if (op[i])
{
outchar[spos++] = allchar[cpos++];
}
else {
out_st[count] += outchar[--spos];
//System.out.print(outchar[--spos]);
}
}
for(int i = 0; i < count; i++)
{
if(out_st[count].equals(out_st[i]))
{
repeat = true;
break;
}
}
if(!repeat)
{
System.out.print((1+count) + ",");
System.out.print(out_st[count]);
System.out.print("\n");
count++;
}
}
}
public static void main(String[] args){
stackout test = new stackout();
//System.out.println(test.M(11));
test.k(N, 0, 0);
}
}

这是java的代码,自行转为c++
freshui 2008-03-12
  • 打赏
  • 举报
回复
这就是中学学的排列组合问题啊
p0303230 2008-03-12
  • 打赏
  • 举报
回复
好像比较容易
wpalhm 2008-03-12
  • 打赏
  • 举报
回复

#include "stdafx.h"
#include <iostream>
#include <string>
#include <algorithm>

typedef std::string::size_type size_t;

void range(std::string& str, size_t beg, size_t end)
{
if( beg == end )
std::cout << str << std::endl;
else
for( size_t i(beg); i!=end; ++i )
{
std::swap( str.at(i), str.at(beg) );
range(str, beg+1, end);
std::swap( str.at(i), str.at(beg) );
}
}

int _tmain(int argc, _TCHAR* argv[])
{
std::string str = "abcde";
range( str, 0, str.size() );

std::cin.get();
return 0;
}

64,312

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧