蛋糕是画图案简单还是挤奶油蛋糕图案简单


写一个函数该函数将把传递过來的数组依次剪掉一个元素,并将处理之后的数组递归调用最开始的时候写一个判断数组元素个数的表达式就行了

而且他是从0-n的一个数組,建议处理的时候把他们全部加1输出时再减1,这样可以用0作为一个数组的终止标志

那这样输出的结果好像跟要求输出的顺序是不一樣的吧?
 比如他先是01,2
你看他的输出先输出的是0,1的非空子集在输出0,1的非空子集后面加一个2(最开始可以理解为空输出加一个2)
那你可以这样递归在前一个量的后面加上本次递归的数字
对于0,返回
NULL(其实没有输出就是空)
0
对于1返回
0的返回值1 1
0的返回值2 1
对于2返回
0的返回值1 2
0的返回值2 2
1的返回值1 2
1的返回值2 2
理解了么?
还是不太理解怎么有两个返回值。如果方便请写一个大概的程序吧多谢了。

你对这个回答的评价是

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

      算法老师留了三个作业给我们額,因为他的题目写在黑板上不能Copy,所以没抄了不过,按照我意思的理解他出的题目就是我这篇文章的题目吧。嗯嗯根据老师的題目,我还是把题目意思写过来

      输出n个数的所有不重复序列,序列之间的数字用空格隔开每个序列占一行。

      输出含有k个数的所有不相哃的集合输出集合的序列按照字典序输出,每个集合占一行集合的相邻两个数字用空格隔开。

      嗯嗯题目意思描述可能和老师描述的囿点差异。请结合Sample Input和Sample Output应该就能看懂了在这篇博文中,老师的题目只是作为引子可能到最后我不会把这三个题目用Code实现,但我会逐渐把峩理解的关于怎样生成全排列和怎样生成子集的知识讲出来OK,就开始我的全排列和子集生成之旅吧

Exceeded)了。不是因为next_permutation的效率而TLE而是我那个时候自以为是的在输入n前加了一个while(true),所以理所当然TLE了呵呵,偶提这个东西只是想让你们知道有很多的基本算法都在STL里面实现了。當然有可能有的同学还不晓得STL为何物,那你就先把她当成是一位PLMM吧

好的,首先我要介绍的是使用递归的思想来实现全排列。我们看測试样例的输出就可以看出在生成全排列的时候,以1开头的的序列首先输出1,然后输出2~n的序列而你把1开始的序列的前面的1去掉,则變成了2~n的按照字典序输出的序列把2开始的序列的前面的2去掉……我相信你对递归了解的话,很显然看到这是一个不断递归的过程按照這个思想,我们只要把递归的过程写出来找到递归的出口,全排列自然就出来了按照这个思想,我就写一个伪代码如何使用:

      额不偠嫌伪代码如何使用有点难看,偶觉得只有能让人很容易明白的伪代码如何使用才是好伪码所以,我找女朋友的标准一直是if(有内涵) 追她;峩不敢使用if(漂亮||有内涵) 追她;虽然有可能让我追到一个(漂亮&&有内涵)的MM但也有可能追到一个(漂亮&&!内涵)的MM。当然你可能会说为什么不把if里面嘚判断语句改为(有内涵&&漂亮)呢?额我没那个资本……话说还是来稍微解释一下那个伪代码如何使用吧。递归的边界应该很好理解吧当集合s[]中没有一个元素的时候,按照上面的伪码s[]中的元素只能向序列a[]中跑,s[]没了元素那么序列a[]就是一个完整的序列了。那么直接输出序列a[]即可。按照从小到大的顺序考虑s[]中的每个元素每次递归的调用以a[]开始。

如果伪码了解了那么就得用代码如何使用实现了。很容易想到序列a[]用数组保存集合s[]中跑过来得数字而s[]呢?如果要完成老师布置的第一个题目那么s[]中的元素根本不要保存,因为s[]中的元素往a[]中跑那么,跑过来得数字就间接的保存在了序列a[]中只要没在序列a[]中出现过的数字都可以备选。由于C/C++传递数组的时候传递的是数组的首地址所以,还需要传一个到底填了多少个数也就是到底填到数组的第几个位置来了,我们把这个参数取名为curOK,下面就用代码如何使用来實现老师布置的第一个题目吧

       可能有很多同学对于递归的机制完全不理解,其实我一直也不是很理解……C/C++语言函数调用自己和调用其怹函数没有什么区别,都是建立新栈(这就是为什么递归次数太多容易stack overflow)传递参数并修改相应的数据。在函数执行完毕的时候删除栈處理返回值并修改相应的数据。打个比较简单的比方如果我想知道CMM是不是喜欢我(LCQ),但我又不能直接问CMM于是,就有了下面这个过程:

于是CMM把不喜欢LCQ这个结果给BMM,BMM又把这个结果返回AMMAMM又把这个不幸的结果告诉LCQ。于是LCQ终于知道了CMM不喜欢他……这就是一个递归的实例。當然这个狗屁比方甚是不好,但是递归基本就是这样一个过程不断的给下一个被递归的函数安排工作。要是你还是没明白递归是啥回倳下面我在word上画了一个当n==3时怎样生成全排列的过程,其中x表示的是未被下一级递归函数不确认的数字图画的不好,凑合着看吧

      好的,递归生成全排列就到此结束如果你还是不怎么理解递归,那就用我在网上看到的另外一种方法实现他的名字叫做字典序生成算法。

峩只是按照这个算法的思想写了一个Code这个算法的思想我是经过查阅网上的blog得到的。在写这篇blog的过程中我参考了很多的文章,我现在不┅一列举等写完这篇博客之后,我会把他们的超链接全部放到后面有些看不懂的东西你们点击超链接去看。比如这个算法为什么这样僦能得到下一个全排列我就不把证明Copy到这个上面了,下面是我按照这个算法写的Code代码如何使用有点繁琐,命名的地方可能有点不规范请大家凑合看一下,你们自己写代码如何使用的时候可以参考一下

      如果说你是一个C++程序设计者,别人问你啥是STL如果你和我在前面一樣说是一位PLMM,那估计就有被别人鄙视的份了STL:Sandard Template Library,中译曰标准模板库更准确的说就是是 C++ 程序设计语言标准模板库。我们大二的时候学过MFC吧MFC是MS创建的 C++ 类库,与之相似的是STL模板库不过呢,STL是 ANSI/ISO 标准的一部分而MFC是MS的一个产品……顺便提一下,经常听见有的同学说我要学Visual C++语言Visual C++只是一个编译器,而不是语言你要学的其实是MFC。

valid即你传的迭代器的范围要合理。然后你看到了有两个重载的对吧,下面一个_Comp意思僦是可以按照你的规则来生成下一个全排列然后看到next_permutation前面的bool了吧,理所当然他的返回值就是bool。返回true的时候这个函数生成下一个全排列,返回false的时候这时候就表明没有下一个全排列了,当然也有可能你传的迭代器不合理等原因。值得一提的是STL完全适应可重集,所鉯老师提的第二个问题完全可以用STL解决,当然第一个问题就更不用说了。下面我用STL来演示一下对于这些"lcq", "love", "code", "plmm"字符串按照字典序把他们的全排列输出来OK,看代码如何使用演示:

      看到STL的强悍了吧那就好好去看看STL吧。你有可能会问这个STL里面的next_permutation到底是怎么实现的啊。不用急洳果你有侯捷的《STL 源码剖析》,请翻开第380页如果没有,那么请接着往下看:

你看了之后会忍不住骂这不就是前面的字典排序的思想吗?是的没错但我还是把侯捷写的源码贴出来了,提醒一下用模板写的代码如何使用和自己写的代码如何使用之间的差别建议在使用STL中嘚算法时,要先明白它到底是怎样实现的如果你只会使用而不知道它是如何实现的,碰到细节问题你可能就束手无策了出来混的,迟早是要还的!感叹一下侯捷写的代码如何使用异常简洁高效……这就是大牛和菜鸟之间的差别~~~

      额,你可能会说老师的第二个题目你还沒做呢,虽然可以用STL中的next_permutation解决但老师肯定不认。好吧我用我自己写的第一个递归函数再来解决一下老师提的第二个问题。

      显然当输叺重复的数字时,必须用一个数组init[]来保存输入的数字然后,只要调用noRepeatPermutation(a, init, n, 0)即可但是,有了重复的数字由于前面的递归程序禁止a[]数组的数芓出现重复,那么你输入3 1 1 1程序那就什么也不输出了。(本来应该输出1 1

1.遗漏倒是没有了可又出现了重复……唉,为什么受伤的人总是我吖!仔细看了代码如何使用问题主要出现在这段代码如何使用实现试着把第一个1作为开头,递归结束之后又用第二个1作为开头递归结束之后又用第三个1作为开头……可实际这三个1是相同的,应该只调用一次而不是三次!我们应该枚举的下标不重复、不遗漏的取遍所有嘚init[i]的值。由于我先调用qsort把init[]排过序那么请在noRepeatPermutation函数里面的第二个for循环后面加上这条语句:if(

      接下来我要重点介绍的一种方法是利用二进制来表礻{1,2,3,……,}的子集S:从右往左用一个整数的二进制表示元素i是不是再集合S中。下面演示了用二进制表示集合{7,6,4,3,1}

      OK,有了这个思想我们就可以把整數想象为二进制的数,实际上我们也知道,整数在机器里面都是用0,1表示的可以这么说,0,1创造了计算机的整个世界这就是为什么判断┅个整数是不是奇数用if(n&1) n为奇数;(奇数用二进制表示末尾一定是1)比用if(1 == n%1) n为奇数;快多了的原因。知道了表示还要知道怎样操作整数来表示集合,這点发明C语言的人早就为我们想到了他们分别是&,| ^.

这段代码如何使用的效率肯定要比前面两段代码如何使用快多了。不过不要得意太早你输入31试试?代码如何使用什么也没输出这是为什么呢?1~30都能输出他的所有子集为什么30以后的就不行了……仔细想想int是多少位你僦明白了……所以还是应了那句话,出来混的迟早是要还的,而前面两段代码如何使用虽然效率低些但只要内存足够,原则上是能输絀1~UINT_MAX的子集

      好了,该是来解决老师提的问题的时候了我比较喜欢第三段代码如何使用。所以把第三段代码如何使用稍微修改一下就能完荿老师的所提的问题了修改后的代码如何使用如下:

      至此为止,老师的问题全部解答完毕.但这个问题有点遗憾的是子集按照非字典顺序輸出的请同学们思考按照字典顺序输出的方法(其实很简单……)

      如果看了这篇文章后想要了解全排列和子集生成掌握得如何,请思考洳下问题:

为什么使用多线程还要保证执行順序呢多线程在运行的时候有专门的机制来分配时间戳,所以楼上那些让线程sleep的方法不一定能保证顺序因为在
分配的时间里,一个线程可能没执行完但是时间到了依然要释放cpu资源。如果非要按照你说的顺序来执行有一个办法是肯定可行的,那就是锁让
后一个线程等待前一个线程的资源锁。以上仅代表个人观点

线程合并 但是你这个例子太快了 看不出来

我要回帖

更多关于 奶油蛋糕图案 的文章

 

随机推荐