今天,介绍一道在本计算机考试书上的阶乘排序(就是将一个列表长度的阶乘种的方式的排列组合输出)题。
下面我们直接看题:
在1~49中任意选择7个数,将这7个数的所有排列可能性全部输出。例如:[1,2,3]的所有输出有[2,1,3];[2,3,1];[3,2,1];[3,1,2];[1,3,2];[1,2,3].
这道题的关键是要找到一个排序的规律,在这里我不介绍各种排序的算法了(其实我也不是很懂o(╥﹏╥)o),只讲自己观察出来的一种规律。
首先,让我们把[1,2,3]的排序所有可能写下来:
这下,我们就能很容易看到这个规律了,其实,只要我们遇到这类题目,使用列举法或假设法都很好的解决问题。正如题目要求的7个,但是,这里我们使用3个数来理解这个问题就变得很简单了。下面我们再来看一张图,就了解这个规律了:
我们只关注一件事,“1”它怎么变动的,我们就能很容易的知道如何解决这道题了。其实,就是简单的将前一个数与后一个数交换位置。且这种交换是循环的,意思是当“1”从头交换到了尾就是一个循环,因为,它没有办法再继续这种交换了。然后,它再从尾交换到头,实现第二个循环。到此,我们已经明白这个规律了。
但是,还有一个问题,怎么确定不同的排序的循环呢?
然后,我们再来延伸,同样寻找规律。在分别列出了2、3、4、5个数时,它的循环数。
咋一看感觉是没有什么规律,但是,当我们将每个数的阶乘写出来了,就可以看出来其实规律还是挺容易发现的。
现在,我们就将这道题的一个规律找出来了,下面,我们就用代码来实现它:
# 首先要导入reduce累积函数,因为我使用的是python3,所以在functools库中。
from functools import reduce
# 定义一个两两交换的排序函数。
def sort_two(lis):
length = len(lis)
# 定义一个循环初始值
count = 1
# 计算阶乘
counts = reduce(lambda x, y: x*y, range(1, length+1))
# 计算循环数
lim = counts/(length-1)
while count <= lim:
count += 1
if not isinstance(lis, list):
return "Please number in list"
for i in range(length-1):
one = lis[i]
two = lis[i+1]
lis[i] = two
lis[i+1] = one
print(lis)
if __name__ == "__main__" :
lis = [1, 2, 3, 4]
sort_two(lis=lis)
输出结果:
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[3, 2, 4, 1]
[3, 4, 2, 1]
[3, 4, 1, 2]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[1, 2, 4, 3]
[1, 2, 3, 4]
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[3, 2, 4, 1]
[3, 4, 2, 1]
[3, 4, 1, 2]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[1, 2, 4, 3]
[1, 2, 3, 4]
一道很有意思的规律题,感觉自己又回到了高中做数学找规律的题的时候,真是非常享受的一件事情(^▽^)。但是,自己关于算法的学习也是冰山一角,再接再厉吧!