求助_关于next_permutation

prosolve 2012-03-24 09:53:12
下面程序运行后没反应,不知哪里错了,各位大侠帮忙看一下吧
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
int c;
string s="000001111111111";
c=3;
while(c!=0);
{
next_permutation(s.begin(),s.end());
cout<<s<<endl;
c--;
}
cout<<s<<endl;
system("pause");
}
...全文
156 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
prosolve 2012-03-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 hello_world000 的回复:]

C/C++ code

while(c!=0);//把后面的分号去掉
[/Quote]
What I all want is what you pount out!Thank you very much!
prosolve 2012-03-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 eit520 的回复:]

void func1()
{
vector<int> v;
INSERT_ELEMENTS(v, 1,3);

PRINT_ELEMENTS( v, "myself: ");

while( next_permutation( v.begin(), v.end() ) )
{

PRINT_ELEMENTS( v,……
[/Quote]
挺好,谢谢
prosolve 2012-03-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 eit520 的回复:]

在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析.

首先查看stl中相关信息.
函数原型:

template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator _……
[/Quote]
挺好,谢谢
EIT王子 2012-03-24
  • 打赏
  • 举报
回复
sort(v.begin(), v.end(), greater<int>() ); //增加排序(降序)
这是一个很关键的地方
EIT王子 2012-03-24
  • 打赏
  • 举报
回复
void func1()
{
vector<int> v;
INSERT_ELEMENTS(v, 1,3);

PRINT_ELEMENTS( v, "myself: ");

while( next_permutation( v.begin(), v.end() ) )
{

PRINT_ELEMENTS( v, "");
}
}


void func2()
{
vector<int> v;

INSERT_ELEMENTS(v, 1,3);

PRINT_ELEMENTS( v, "myself: ");

sort(v.begin(), v.end(), greater<int>() ); //增加排序(降序)

while( prev_permutation( v.begin(), v.end() ) )
{

PRINT_ELEMENTS( v, "");
}
}


如果以后再遇到类似问题,我们就如此如此,不用再费脑筋,人家有现成的函数,直接拿来用就是了。



另外普及一下:

下面这段才是真真的算法,STL里面的源码
  template inline
   bool next_permutation(_BidIt _First, _BidIt _Last)
   { // permute and test for pure ascending, using operator<
   _BidIt _Next = _Last;
   if (_First == _Last || _First == --_Next)
   return (false);
  
   for (; ; )
   { // find rightmost element smaller than successor
   _BidIt _Next1 = _Next;
   if (*--_Next < *_Next1)
   { // swap with rightmost element that's smaller, flip suffix
   _BidIt _Mid = _Last;
   for (; !(*_Next < *--_Mid); )
   ;
   std::iter_swap(_Next, _Mid);
   std::reverse(_Next1, _Last);
   return (true);
   }
  
   if (_Next == _First)
   { // pure descending, flip all
   std::reverse(_First, _Last);
   return (false);
   }
   }
   }
  
  
  Ps: "STL":Standard Template Library,标准模板库(摘录bbs.csdn.net)
   这是最早由Alexander Stepanov和Meng Lee(好像是华人的名字哦)完成,于1994年提交给ANSI/ISO 标准C++委员会并通过而成为标准C++的一部分。望文生义即可知这是一个代码库标准,不是语法标准。简单地说,STL是以C++中的模板语法为基础建立起来的一套包含基础数据结构和算法的代码库。STL的特点是实现了“类型参数化”,即STL的代码中可处理任意自定义类型的对象,如果不使用模板技术的话,这是一件相当困难的事。也因为这个原因,在最新的java及C#语法中均加入了对模板语法的支持,可见其重要性。另外一个有关STL重要的话题是GP(Generic Programming),泛型。这是与面向对象相并列的另外的一个编程模型,它以模板为基础,弱化了实体类型的差异,简化了编程时问题抽象的模型,提供了更好的封装性和弹性,对于繁杂的面向对象编程毫无疑问是一种解脱,至少是精神上的。GP是最近几年软件架构的一个研究热点,但国内真正的应用似乎并不多见。
EIT王子 2012-03-24
  • 打赏
  • 举报
回复
在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析.

首先查看stl中相关信息.
函数原型:

template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template<class BidirectionalIterator, class BinaryPredicate>
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的所有排列。
月中蓝 2012-03-24
  • 打赏
  • 举报
回复
楼主看到这一句了吗?
sort (s.begin(),s.end());
prosolve 2012-03-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]

C/C++ code
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
int c;
string s="000001111111111";
c=3;
sort (s.begin(),s.end());
while(c!……
[/Quote]
大侠,为什么我把next_permutation放到循环里面就不对呢
pengzhixi 2012-03-24
  • 打赏
  • 举报
回复
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
int c;
string s="000001111111111";
c=3;
sort (s.begin(),s.end());
while(c!=0&&next_permutation(s.begin(),s.end()))
{
cout<<s<<endl;
c--;
}
cout<<s<<endl;

system("pause");
return 0;
}
hello_world000 2012-03-24
  • 打赏
  • 举报
回复

while(c!=0);//把后面的分号去掉

64,649

社区成员

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

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