由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 如何写内存速度最优化的string permutation?有重复字符
相关主题
实现next_permutationMS Onsite
调试成功的next_permutation代码今天才整明白Permutation的最优解!?
Exposed上一道string permutation的题amazon onsite 面经
Given a string, find all its permutations without any repetition?一道题:number of permutation是 for a total score
T家电面面经并且不解为何被秒拒leetcode里, backtracking的time complexity怎么算,比如permutations这题目
How to handle the return type of container.size() in C++请教一道Leetcode 题
这两道leetcode题有更好的答案吗?permuation sequence 超时
也报个G家intern面经如何避免permutation中的重复计数
相关话题的讨论汇总
话题: char话题: end话题: int话题: str
进入JobHunting版参与讨论
1 (共1页)
w**t
发帖数: 592
1
题目是写一个memory and/or speed优化的程序,只有一个输入值,不能用hash map,
如何写?string有重复字符
比如 void perm(const char* str)
我给出的是用递归+hash map,所有中间变量用static variable,permuted string放
在一个static hash map 里。显然
他不认为是最优解。
g***s
发帖数: 3811
2
please refer to next_permutation in stl.

【在 w**t 的大作中提到】
: 题目是写一个memory and/or speed优化的程序,只有一个输入值,不能用hash map,
: 如何写?string有重复字符
: 比如 void perm(const char* str)
: 我给出的是用递归+hash map,所有中间变量用static variable,permuted string放
: 在一个static hash map 里。显然
: 他不认为是最优解。

w**t
发帖数: 592
3
谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?

【在 g***s 的大作中提到】
: please refer to next_permutation in stl.
g***s
发帖数: 3811
4
try to under next_permutation's implementation. it doesn't need any hash
or any recursive call. in-place swap is enough.
i think the interviewer just hoped you to write a good next_permutation
codes.

【在 w**t 的大作中提到】
: 谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?
l*********8
发帖数: 4642
5
next_permutation 能处理重复字符的情况吗?

【在 g***s 的大作中提到】
: try to under next_permutation's implementation. it doesn't need any hash
: or any recursive call. in-place swap is enough.
: i think the interviewer just hoped you to write a good next_permutation
: codes.

g***s
发帖数: 3811
6
why not?

【在 l*********8 的大作中提到】
: next_permutation 能处理重复字符的情况吗?
g**********y
发帖数: 14569
7
先把字符排序,然后对每个不同的字符(个数是len)来递归。相当于把len个字符插进前面的生成串里,总共有C(n+len, len)种方式。
这是java code
好象这也是G喜欢问的一道题,面试时写出来还是很吃力的。程序不难,但是那些递归关系和边界条件想清楚,很费脑力。我觉得谁要不用debugger, 一遍把它写对,差不多就可以把G拿下了。
public class RepetitionPermute {
public void permute(String a) {
char[] c = a.toCharArray();
Arrays.sort(c);
permute("", c, 0);
}

private void permute(String s, char[] c, int begin) {
if (begin == c.length) {
System.out.println(s);
return;
}

int end = begin+1;
while (end < c.length && c[end]==c[begin]) end++;
int len = end - begin;

permute(s, c[begin], len, 0, c, end);
}

private void permute(String s, char ch, int len, int start, char[] c,
int begin) {
if (len == 0) {
permute(s, c, begin);
return;
}

String fill = "";
for (int i=0; i fill += ch;
for (int j=start; j<=s.length(); j++) {
permute(s.substring(0, j) + fill + s.substring(j), ch, len-i
-1, j+i+2, c, begin);
}
}
}

public static void main(String[] args) {
new RepetitionPermute().permute("abc");
}
}

【在 w**t 的大作中提到】
: 谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?
j*******r
发帖数: 52
8
试贴一个C++代码,循环+递归,用一个bitset代表当前字符是否已经在之前位置被使用。
1 #include
2 #include
3 #include
4
5 using namespace std;
6
7 void permutation(const char* str, bitset<4> used, string r){
8 if(r.size() == strlen(str)){
9 cout< 10 }
11 for(int i = 0; i < strlen(str); ++i){
12 if(used[i])
13 continue;
14 used.set(i);
15 r += str[i];
16 permutation(str, used, r);
17 r.erase(r.size()-1);
18 used[i]=0;
19 }
20 return;
21 }
22
23 int main(){
24 string s = "abcd";
25 bitset<4> used;
26 string r = "";
27 permutation(s.c_str(), used, r);
28 return 1;
29 }
g***s
发帖数: 3811
9
7 lou and 8 lou:
please test input='aa' for both of your codes.
g**e
发帖数: 6127
10
大牛,如何提高迅速发现代码bug的功力?这个还是需要平时的积累是吗

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

相关主题
How to handle the return type of container.size() in C++MS Onsite
这两道leetcode题有更好的答案吗?今天才整明白Permutation的最优解!?
也报个G家intern面经amazon onsite 面经
进入JobHunting版参与讨论
g***s
发帖数: 3811
11
无他,但手熟尔

【在 g**e 的大作中提到】
: 大牛,如何提高迅速发现代码bug的功力?这个还是需要平时的积累是吗
g***s
发帖数: 3811
12
无他,惟手熟尔

【在 g**e 的大作中提到】
: 大牛,如何提高迅速发现代码bug的功力?这个还是需要平时的积累是吗
j*******r
发帖数: 52
13
重复字符是很头疼,不写代码了。
lz看这儿吧
http://marknelson.us/2002/03/01/next-permutation/

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

g**********y
发帖数: 14569
14
谢谢,边界条件错了一位。改成j+i+2就行了。

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

f****4
发帖数: 1359
15
重复字符permutation怎么算啊?比如
“aa”,permutation是2个还是1个?
我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
g++,stl
input:
1, 2, 2, 3
output:
1 2 2 3
1 2 3 2
1 3 2 2
2 1 2 3
2 1 3 2
2 2 1 3
2 2 3 1
2 3 1 2
2 3 2 1
3 1 2 2
3 2 1 2
3 2 2 1
input:
1, 4, 3, 2
output:
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1
第二个明显就是错的。。。

【在 g***s 的大作中提到】
: why not?
g**********y
发帖数: 14569
16
aa的permutation当然只有一个。

集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_
permutation算法);重复字符permutation不算重复的

【在 f****4 的大作中提到】
: 重复字符permutation怎么算啊?比如
: “aa”,permutation是2个还是1个?
: 我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
: g++,stl
: input:
: 1, 2, 2, 3
: output:
: 1 2 2 3
: 1 2 3 2
: 1 3 2 2

g***s
发帖数: 3811
17
ft. why don't you sort it first?
next_permutation("aa",0,2) should return false.

集是默认排
序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);
重复字符
permutation不算重复的

【在 f****4 的大作中提到】
: 重复字符permutation怎么算啊?比如
: “aa”,permutation是2个还是1个?
: 我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
: g++,stl
: input:
: 1, 2, 2, 3
: output:
: 1 2 2 3
: 1 2 3 2
: 1 3 2 2

f****4
发帖数: 1359
18
恩,我一直对假设条件搞不清楚
比如这里。。。

【在 g***s 的大作中提到】
: ft. why don't you sort it first?
: next_permutation("aa",0,2) should return false.
:
: 集是默认排
: 序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);
: 重复字符
: permutation不算重复的

s*****y
发帖数: 897
19
http://zebozhuang.blog.163.com/blog/static/17147980420112710523
在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组
数据的全排列.但是怎么用,原理如何,我做了简单的剖析.
首先查看stl中相关信息.
函数原型:
template
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last,
BinaryPredicate _Comp
);
两个重载函数,第二个带谓词参数_Comp,其中只带两个参数的版本,默认谓词函数为"小
于".
返回值:bool类型
分析next_permutation函数执行过程:
假设数列 d1,d2,d3,d4……
范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照
字典序。例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确
定这个下一排列为字典序中的next,而不是next->next->next……
若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最
小字典序。
返回为true表示生成下一排列成功。下面着重分析此过程:
根据标记从后往前比较相邻两数据,若前者小于(默认为小于)后者,标志前者为X1(
位置PX)表示将被替换,再次重后往前搜索第一个不小于X1的数据,标记为X2。交换X1
,X2,然后把[PX+1,last)标记范围置逆。完成。
要点:为什么这样就可以保证得到的为最小递增。
从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。[PX+1,last
)总是递减的,[first,PX)没有改变,因为 X2>X1,所以不管X2后面怎样排列都比原数列
大,反转[PX+1,last)使此子数列(递增)为最小。从而保证的新数列为原数列的字典
序排列 next。
明白了这个原理后,看下面例子:
int main(){
int a[] = {3,1,2};
do{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (next_permutation(a,a+3));
return 0;
}
输出:312/321 因为原数列不是从最小字典排列开始。
所以要想得到所有全排列
int a[] = {3,1,2}; change to int a[] = {1,2,3};
另外,库中另一函数prev_permutation与next_permutation相反,由原排列得到字典序
中上一次最近排列。
所以
int main(){
int a[] = {3,2,1};
do{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (prev_permutation(a,a+3));
return 0;
}
才能得到123的所有排列。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aipb2008/archive/2008/03/29/2227490.aspx
s*****y
发帖数: 897
20
根据题目和next_permutation 的实现,写了个相应的,assume input string is
sorted
inline void swap(char *i, char *j) {
char tmp = *i;
*i = *j;
*j = tmp;
}
inline void reverse(char *start, char *end){
while (start < end) {
swap(start, end);
start ++;
end--;
}
}
bool perm_loop(char *str, char *start, char *end) {
char *i = end-1;
//find first two pairs from the end that *i < *(i+1)
while((i >= start) &&(*i >= *(i+1))) i--;
//could not find such pair
if (i < start) return false;
//search from the end for the first *ii that is bigger than *i, worse
case it will be *ii = *(i+1)
char *ii;
for (ii = end; *ii < *i; ii--) ;
swap(i, ii);
reverse(i+1, end);
return true;
}
void perm(char *str) {
if (!str) return; //zero element
int size = 0;
char *tmp = str;
char *start = str;
while (*tmp++) size++;
char *end = str + size -1;
if (start == end) return; //one element
do {
cout << str << endl;
}while (perm_loop(str, start, end) ) ;

//recover the string
reverse(start, end);
}
int main () {
char input[] = "123";
perm(input);
return 0;
}
相关主题
一道题:number of permutation是 for a total scorepermuation sequence 超时
leetcode里, backtracking的time complexity怎么算,比如permutations这题目如何避免permutation中的重复计数
请教一道Leetcode 题LeetCode Runtime Error 一问
进入JobHunting版参与讨论
i**********e
发帖数: 1145
21
My code below, using this article as reference (excellent explanation, very
easy to understand, just skip to "What's happening here"):
http://wordaligned.org/articles/next-permutation#tocwhats-happe
And here is a problem from Google CodeJam which uses nextPermutation.
http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
void rev(int num[], int start, int end) {
while (start < end) {
swap(num[start], num[end]);
start++;
end--;
}
}
//
bool nextPermutation(int num[], int n) {
int tail = n-1;
int head = tail-1;
while (head >= 0 && num[head] >= num[head+1]) {
head--;
}
if (head < 0) return false;
while (num[tail] <= num[head]) {
tail--;
}
assert(tail > head);
swap(num[head], num[tail]);
rev(num, head+1, n-1);
return true;
}
一些常见面试题的答案与总结 -
http://www.ihas1337code.com
g**********y
发帖数: 14569
22
我把程序转成Java, 代入{1, 1, 1, 2, 2, 3}进去,打印了一组数就出来了。

very

【在 i**********e 的大作中提到】
: My code below, using this article as reference (excellent explanation, very
: easy to understand, just skip to "What's happening here"):
: http://wordaligned.org/articles/next-permutation#tocwhats-happe
: And here is a problem from Google CodeJam which uses nextPermutation.
: http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
: void rev(int num[], int start, int end) {
: while (start < end) {
: swap(num[start], num[end]);
: start++;
: end--;

f****4
发帖数: 1359
23
这个解释很赞~

very

【在 i**********e 的大作中提到】
: My code below, using this article as reference (excellent explanation, very
: easy to understand, just skip to "What's happening here"):
: http://wordaligned.org/articles/next-permutation#tocwhats-happe
: And here is a problem from Google CodeJam which uses nextPermutation.
: http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
: void rev(int num[], int start, int end) {
: while (start < end) {
: swap(num[start], num[end]);
: start++;
: end--;

w**t
发帖数: 592
24
题目是写一个memory and/or speed优化的程序,只有一个输入值,不能用hash map,
如何写?string有重复字符
比如 void perm(const char* str)
我给出的是用递归+hash map,所有中间变量用static variable,permuted string放
在一个static hash map 里。显然
他不认为是最优解。
g***s
发帖数: 3811
25
please refer to next_permutation in stl.

【在 w**t 的大作中提到】
: 题目是写一个memory and/or speed优化的程序,只有一个输入值,不能用hash map,
: 如何写?string有重复字符
: 比如 void perm(const char* str)
: 我给出的是用递归+hash map,所有中间变量用static variable,permuted string放
: 在一个static hash map 里。显然
: 他不认为是最优解。

w**t
发帖数: 592
26
谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?

【在 g***s 的大作中提到】
: please refer to next_permutation in stl.
g***s
发帖数: 3811
27
try to under next_permutation's implementation. it doesn't need any hash
or any recursive call. in-place swap is enough.
i think the interviewer just hoped you to write a good next_permutation
codes.

【在 w**t 的大作中提到】
: 谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?
l*********8
发帖数: 4642
28
next_permutation 能处理重复字符的情况吗?

【在 g***s 的大作中提到】
: try to under next_permutation's implementation. it doesn't need any hash
: or any recursive call. in-place swap is enough.
: i think the interviewer just hoped you to write a good next_permutation
: codes.

g***s
发帖数: 3811
29
why not?

【在 l*********8 的大作中提到】
: next_permutation 能处理重复字符的情况吗?
g**********y
发帖数: 14569
30
先把字符排序,然后对每个不同的字符(个数是len)来递归。相当于把len个字符插进前面的生成串里,总共有C(n+len, len)种方式。
这是java code
好象这也是G喜欢问的一道题,面试时写出来还是很吃力的。程序不难,但是那些递归关系和边界条件想清楚,很费脑力。我觉得谁要不用debugger, 一遍把它写对,差不多就可以把G拿下了。
public class RepetitionPermute {
public void permute(String a) {
char[] c = a.toCharArray();
Arrays.sort(c);
permute("", c, 0);
}

private void permute(String s, char[] c, int begin) {
if (begin == c.length) {
System.out.println(s);
return;
}

int end = begin+1;
while (end < c.length && c[end]==c[begin]) end++;
int len = end - begin;

permute(s, c[begin], len, 0, c, end);
}

private void permute(String s, char ch, int len, int start, char[] c,
int begin) {
if (len == 0) {
permute(s, c, begin);
return;
}

String fill = "";
for (int i=0; i fill += ch;
for (int j=start; j<=s.length(); j++) {
permute(s.substring(0, j) + fill + s.substring(j), ch, len-i
-1, j+i+2, c, begin);
}
}
}

public static void main(String[] args) {
new RepetitionPermute().permute("abc");
}
}

【在 w**t 的大作中提到】
: 谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?
相关主题
iterative string permutation调试成功的next_permutation代码
关于排列组合的题目的算法Exposed上一道string permutation的题
实现next_permutationGiven a string, find all its permutations without any repetition?
进入JobHunting版参与讨论
j*******r
发帖数: 52
31
试贴一个C++代码,循环+递归,用一个bitset代表当前字符是否已经在之前位置被使用。
1 #include
2 #include
3 #include
4
5 using namespace std;
6
7 void permutation(const char* str, bitset<4> used, string r){
8 if(r.size() == strlen(str)){
9 cout< 10 }
11 for(int i = 0; i < strlen(str); ++i){
12 if(used[i])
13 continue;
14 used.set(i);
15 r += str[i];
16 permutation(str, used, r);
17 r.erase(r.size()-1);
18 used[i]=0;
19 }
20 return;
21 }
22
23 int main(){
24 string s = "abcd";
25 bitset<4> used;
26 string r = "";
27 permutation(s.c_str(), used, r);
28 return 1;
29 }
g***s
发帖数: 3811
32
7 lou and 8 lou:
please test input='aa' for both of your codes.
g**e
发帖数: 6127
33
大牛,如何提高迅速发现代码bug的功力?这个还是需要平时的积累是吗

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

g***s
发帖数: 3811
34
无他,惟手熟尔

【在 g**e 的大作中提到】
: 大牛,如何提高迅速发现代码bug的功力?这个还是需要平时的积累是吗
j*******r
发帖数: 52
35
重复字符是很头疼,不写代码了。
lz看这儿吧
http://marknelson.us/2002/03/01/next-permutation/

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

g**********y
发帖数: 14569
36
谢谢,边界条件错了一位。改成j+i+2就行了。

【在 g***s 的大作中提到】
: 7 lou and 8 lou:
: please test input='aa' for both of your codes.

f****4
发帖数: 1359
37
重复字符permutation怎么算啊?比如
“aa”,permutation是2个还是1个?
我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
g++,stl
input:
1, 2, 2, 3
output:
1 2 2 3
1 2 3 2
1 3 2 2
2 1 2 3
2 1 3 2
2 2 1 3
2 2 3 1
2 3 1 2
2 3 2 1
3 1 2 2
3 2 1 2
3 2 2 1
input:
1, 4, 3, 2
output:
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1
第二个明显就是错的。。。

【在 g***s 的大作中提到】
: why not?
g**********y
发帖数: 14569
38
aa的permutation当然只有一个。

集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_
permutation算法);重复字符permutation不算重复的

【在 f****4 的大作中提到】
: 重复字符permutation怎么算啊?比如
: “aa”,permutation是2个还是1个?
: 我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
: g++,stl
: input:
: 1, 2, 2, 3
: output:
: 1 2 2 3
: 1 2 3 2
: 1 3 2 2

g***s
发帖数: 3811
39
ft. why don't you sort it first?
next_permutation("aa",0,2) should return false.

集是默认排
序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);
重复字符
permutation不算重复的

【在 f****4 的大作中提到】
: 重复字符permutation怎么算啊?比如
: “aa”,permutation是2个还是1个?
: 我的理解是如果要输出所有permutation的结果,那么next_permutation对输入字符集是默认排序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);重复字符permutation不算重复的
: g++,stl
: input:
: 1, 2, 2, 3
: output:
: 1 2 2 3
: 1 2 3 2
: 1 3 2 2

f****4
发帖数: 1359
40
恩,我一直对假设条件搞不清楚
比如这里。。。

【在 g***s 的大作中提到】
: ft. why don't you sort it first?
: next_permutation("aa",0,2) should return false.
:
: 集是默认排
: 序的(就是说,对任意字符集输入,得先排序,才能使用类next_permutation算法);
: 重复字符
: permutation不算重复的

相关主题
Given a string, find all its permutations without any repetition?这两道leetcode题有更好的答案吗?
T家电面面经并且不解为何被秒拒也报个G家intern面经
How to handle the return type of container.size() in C++MS Onsite
进入JobHunting版参与讨论
s*****y
发帖数: 897
41
http://zebozhuang.blog.163.com/blog/static/17147980420112710523
在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组
数据的全排列.但是怎么用,原理如何,我做了简单的剖析.
首先查看stl中相关信息.
函数原型:
template
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last,
BinaryPredicate _Comp
);
两个重载函数,第二个带谓词参数_Comp,其中只带两个参数的版本,默认谓词函数为"小
于".
返回值:bool类型
分析next_permutation函数执行过程:
假设数列 d1,d2,d3,d4……
范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照
字典序。例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确
定这个下一排列为字典序中的next,而不是next->next->next……
若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最
小字典序。
返回为true表示生成下一排列成功。下面着重分析此过程:
根据标记从后往前比较相邻两数据,若前者小于(默认为小于)后者,标志前者为X1(
位置PX)表示将被替换,再次重后往前搜索第一个不小于X1的数据,标记为X2。交换X1
,X2,然后把[PX+1,last)标记范围置逆。完成。
要点:为什么这样就可以保证得到的为最小递增。
从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。[PX+1,last
)总是递减的,[first,PX)没有改变,因为 X2>X1,所以不管X2后面怎样排列都比原数列
大,反转[PX+1,last)使此子数列(递增)为最小。从而保证的新数列为原数列的字典
序排列 next。
明白了这个原理后,看下面例子:
int main(){
int a[] = {3,1,2};
do{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (next_permutation(a,a+3));
return 0;
}
输出:312/321 因为原数列不是从最小字典排列开始。
所以要想得到所有全排列
int a[] = {3,1,2}; change to int a[] = {1,2,3};
另外,库中另一函数prev_permutation与next_permutation相反,由原排列得到字典序
中上一次最近排列。
所以
int main(){
int a[] = {3,2,1};
do{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (prev_permutation(a,a+3));
return 0;
}
才能得到123的所有排列。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aipb2008/archive/2008/03/29/2227490.aspx
s*****y
发帖数: 897
42
根据题目和next_permutation 的实现,写了个相应的,assume input string is
sorted
inline void swap(char *i, char *j) {
char tmp = *i;
*i = *j;
*j = tmp;
}
inline void reverse(char *start, char *end){
while (start < end) {
swap(start, end);
start ++;
end--;
}
}
bool perm_loop(char *str, char *start, char *end) {
char *i = end-1;
//find first two pairs from the end that *i < *(i+1)
while((i >= start) &&(*i >= *(i+1))) i--;
//could not find such pair
if (i < start) return false;
//search from the end for the first *ii that is bigger than *i, worse
case it will be *ii = *(i+1)
char *ii;
for (ii = end; *ii < *i; ii--) ;
swap(i, ii);
reverse(i+1, end);
return true;
}
void perm(char *str) {
if (!str) return; //zero element
int size = 0;
char *tmp = str;
char *start = str;
while (*tmp++) size++;
char *end = str + size -1;
if (start == end) return; //one element
do {
cout << str << endl;
}while (perm_loop(str, start, end) ) ;

//recover the string
reverse(start, end);
}
int main () {
char input[] = "123";
perm(input);
return 0;
}
i**********e
发帖数: 1145
43
My code below, using this article as reference (excellent explanation, very
easy to understand, just skip to "What's happening here"):
http://wordaligned.org/articles/next-permutation#tocwhats-happe
And here is a problem from Google CodeJam which uses nextPermutation.
http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
void rev(int num[], int start, int end) {
while (start < end) {
swap(num[start], num[end]);
start++;
end--;
}
}
//
bool nextPermutation(int num[], int n) {
int tail = n-1;
int head = tail-1;
while (head >= 0 && num[head] >= num[head+1]) {
head--;
}
if (head < 0) return false;
while (num[tail] <= num[head]) {
tail--;
}
assert(tail > head);
swap(num[head], num[tail]);
rev(num, head+1, n-1);
return true;
}
一些常见面试题的答案与总结 -
http://www.ihas1337code.com
g**********y
发帖数: 14569
44
我把程序转成Java, 代入{1, 1, 1, 2, 2, 3}进去,打印了一组数就出来了。

very

【在 i**********e 的大作中提到】
: My code below, using this article as reference (excellent explanation, very
: easy to understand, just skip to "What's happening here"):
: http://wordaligned.org/articles/next-permutation#tocwhats-happe
: And here is a problem from Google CodeJam which uses nextPermutation.
: http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
: void rev(int num[], int start, int end) {
: while (start < end) {
: swap(num[start], num[end]);
: start++;
: end--;

f****4
发帖数: 1359
45
这个解释很赞~

very

【在 i**********e 的大作中提到】
: My code below, using this article as reference (excellent explanation, very
: easy to understand, just skip to "What's happening here"):
: http://wordaligned.org/articles/next-permutation#tocwhats-happe
: And here is a problem from Google CodeJam which uses nextPermutation.
: http://code.google.com/codejam/contest/dashboard?c=186264#s=p1
: void rev(int num[], int start, int end) {
: while (start < end) {
: swap(num[start], num[end]);
: start++;
: end--;

k***t
发帖数: 276
46
Good explanation! Very straightforward.
What about next_combination()? There is some code online, no straightforward
explanation though.
http://stackoverflow.com/questions/127704/algorithm-to-return-a
template
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Mark Nelson http://marknelson.us */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator i1 = first;
Iterator i2 = last;
++i1;
if (last == i1)
return false;
i1 = last;
--i1;
i1 = k;
--i2;
while (first != i1)
{
if (*--i1 < *i2)
{
Iterator j = k;
while (!(*i1 < *j)) ++j;
std::iter_swap(i1,j);
++i1;
++j;
i2 = k;
std::rotate(i1,j,last);
while (last != j)
{
++j;
++i2;
}
std::rotate(k,i2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}

【在 s*****y 的大作中提到】
: http://zebozhuang.blog.163.com/blog/static/17147980420112710523
: 在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组
: 数据的全排列.但是怎么用,原理如何,我做了简单的剖析.
: 首先查看stl中相关信息.
: 函数原型:
: template
: bool next_permutation(
: BidirectionalIterator _First,
: BidirectionalIterator _Last
: );

1 (共1页)
进入JobHunting版参与讨论
相关主题
如何避免permutation中的重复计数T家电面面经并且不解为何被秒拒
LeetCode Runtime Error 一问How to handle the return type of container.size() in C++
iterative string permutation这两道leetcode题有更好的答案吗?
关于排列组合的题目的算法也报个G家intern面经
实现next_permutationMS Onsite
调试成功的next_permutation代码今天才整明白Permutation的最优解!?
Exposed上一道string permutation的题amazon onsite 面经
Given a string, find all its permutations without any repetition?一道题:number of permutation是 for a total score
相关话题的讨论汇总
话题: char话题: end话题: int话题: str