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.
| | | 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;
} | | | 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 的大作中提到】 : 谢谢回复,我也给了这个答案,但是他们想让我自己写。有没有别的好方法呢?
| | | 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不算重复的
| | | 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 : );
|
|