目录
引入:
排列组合:
排列组合是组合学最基本的概念。所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序。组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。
通过C语言实现排列组合,然后再排列组合中加入适当的判断,便可以利用电脑进行简单的逻辑推理!
算法介绍:
排列方式:将所需排列的每个元素按照顺序写入第一个位置,再将剩下的的元素按照顺序写入第二个位置,以此类推,将全部元素写入每个位置中。需要注意的是再每个元素写入后需要将其换回,使每次排列后还能使每个元素回到输入时的位置,这样才能保证下一次分配位置的时候是另一种不同的分类,不会导致重复排序。
人为排列思维方式:
例:排列1 2 3这三个数
输入顺序为1 2 3
第一次排序:将1 2 3 三个数分别写入第一个空
1 _ _
2 _ _
3 _ _
第二次排序:
将每个排列后的剩下的元素依次写入第二个空
12 _ 13 _
21 _ 23 _
31 _ 32 _
第三次排序:
将剩下的元素写入第三个空
123 132
213 231
312 321
上述排列过程主要是人们思考时采用的方式,因为这种排列方式可以非常明显的看出包含了每一种排列方式,而对其中的排列顺序稍加修改,便可以很好的写出我们的递归程序
递归思维方式:
同样是排列1 2 3
第一次排序:将1 2 3 三个数分别写入第一个空
1 _ _
在此时先不着急将别的元素写入第一个位置列排序,而是递归调用我们的写入函数,将剩下的元素依次写入第二个位置:
第二次排序:
将每个排列后的剩下的元素依次写入第二个空
12 _
将2放入第二个位置后先不着急将另一个元素放入第三个,而此时我们递归调用写入函数,将剩下的元素写入第三个位置中,
第三次排序:
123
此时该次的递归调用结束,放回上一级(对13_的排序)(注意,再结束递归调用后,每次返回上一级的时候都还需要将每个元素换回之前的位置,这样下一次排列才是正确的)
13 _ ....同上调用
2 _ _同上
3 _ _同上
通过以上操作便可以很好的对一组数字进行排序。(尽量表达清楚了,如果还是不懂可以私信鸭,表达能力有限)
例题及代码实现:
题解:依据每个选手说的话写出判断逻辑,后再运用全排列,对每种可能的排列进行判断即可。
void swap(char* a, char* b) //交换代码
{
char temp = *a;
*a = *b;
*b = temp;
}
void order(char* rank,int start, int length)//排列函数,参数分别为:需要排列的元素数组,开始放入的位置,元素个数
{
if (start == length ) {
if ((rank[1] == 'b') + (rank[2] == 'a')==1
&& (rank[1] == 'b') + (rank[3] == 'e')==1
&& (rank[0] == 'c') +( rank[1] == 'd')==1
&& (rank[4] == 'c') +( rank[2] == 'd')==1
&& (rank[3] == 'e')+( rank[0] == 'a')==1
) //判断逻辑,只要有符合的就打印并且break
{
for (int i = 0; i < 5; i++) {
printf("%d名为%c\n", i + 1, rank[i]);
}
return;
}
/* for (int i = 0; i < 5; i++) {//次注释为打印出每种排列
printf("%c", rank[i]);
}
printf("\n");
return;*/
}
for (int i = start; i < length; i++) {
swap(&rank[start], &rank[i]); //将每个元素放入start位置
order(rank, start + 1, length); //将每个元素一次放入start+1的位置上
swap(&rank[start], &rank[i]); //将元素换回,以便下次循环的排列
}
}
int main() {
char rank[5] = { 'a','b','c','d','e'};
order(rank, 0, 5);
}
结果展示: