日常记录2(全排列参考)
今儿遇到一道题。先贴一下题目:(反正题目看不看也没用)
两个乒乓球队进行比赛,各出三人。甲队为A,B,C三人,乙队为X,Y,Z三人。
已抽签决定 比赛名单,有人向队员打听比赛的名单,A说他不和X比,C说他不和X、Z比,编程找出三对选手的对手名单。
这需要逻辑推理麽。。很明显的答案嘛。但是要编程解决那我们就编个程序来看看。
想起来以前写过的八皇后demo,于是想着要顺便着写个全排列来试试。
全排列,全排列,全排列,不就是一个All_Sort函数一个issafe函数麽。说写好就写好。而且还没有回溯的一个递归。有啥难度。
写好跑一下,发现居然只输出了一组数据,纳尼(⊙o⊙)?为啥只有一组数据啊。
贴一下刚开始的demo:
char A[3]={'A','B','C'}; char B[3]={'X','Y','Z'}; char result[3]={}; bool issafe(int step,char tmp) { bool ret = false; for(int i = 0;i<3;i++) { if(result[i]==tmp) { ret = true; } } return ret; } void All_Sort(int step) { if(step ==3){ for(int i=0;i<3;i++) printf("%c",result[i]); printf("\n"); return; } for(int i=0;i<3;i++) { if(!issafe(step,B[i])) { result[step] = B[i]; All_Sort(step+1); } } }
感觉看上去没有什么问题啊,但是总感觉有些不对。。。
issafe函数,issafe函数,issafe函数,眼神一瞄,肯定是你小子出了问题(其实是我偷偷看了以前写的博客。。。(lll¬ω¬))
issafe函数应该从0比较到step啊!!比较到3(也就是最后一位的话就没法继续第二次循环了。第一次循环把所有的元素都填充到了result数组中,那肯定所有的元素都有用过,最后一步回溯的时候没法改变最后一位(第二次结果不就是XZY麽,就是退后一步,然后第二位填充最后一个元素))
最后贴一下好用的demo:
//全排列(参考八皇后)然后排除return;符合条件的打印 char A[3]={'A','B','C'}; char B[3]={'X','Y','Z'}; char result[3]={}; bool issafe(int step,char tmp) { bool ret = false; for(int i = 0;i<step;i++) { if(result[i]==tmp) { ret = true; } } return ret; } void All_Sort(int step) { if(step ==3){ for(int i=0;i<3;i++) printf("%c",result[i]); printf("\n"); return; } for(int i=0;i<3;i++) { if(!issafe(step,B[i])) { result[step] = B[i]; All_Sort(step+1); } } }
大多数想法要么平庸,要么更糟糕,这很大程度上因为绝妙的想法难得一见,而且他们还要在我们身边这个充斥了各种恶俗的所谓常识的环境中孕育生长。