下午看到一个问题,是关于求解列表中的平衡点的,感觉挺有意思的,说实在的,最开始看的时候没看明白是什么意思,以至于自己的思路陷进去很深走不出来,后来看了一下给出来的代码实现明白了,是怎么回事。
如;numbers = [1,3,5,7,8,2,4,20],对于这样一个列表,他的平衡点就是2,因为定义的可以有两个子列表的和是一样的,网上的实现说的很简单,但是真的看过以后觉得如果结合lambda函数和fileter函数的话5行以内就解决了吧,还有一个问题就是:这样的代码只有对这样固定形式的数据有用,比如:数据必须是平衡点要么没有要么就是出现在正好能够分割列表的中间的位置,以此平衡点分割后得到的两个子列表正好和相同,但是这样的话感觉意义不是太大。
这里打算写一下,给定一个列表,我要找到其中所有的平衡点,比如对于上面的列表,我交换或者打乱数据之后依旧是可以找到不打乱数据的时候可以找到的平衡点的,此外,这样的平衡点定义放宽之后变成了:指定一个列表,如果存在去除该点后列表可以分为两个和相等的子列表那么就称该点为平衡点。这是对这种题目我给出来的定义。至于解决思路也是比较简单的,可以遍历列表,每次弹出去一个数字,之后划分列表,看是否能够有划分的到两个和相等的子列表这样的操作,如果有的话就记录为平衡点,如果没有继续遍历直至结束,在划分列表的阶段因为实在没有想到采用什么样的方法比较好,这里选择了最笨的方法就是:得到一个列表的所有子列表的方法,规定:空列表不是子列表,所以这里的子列表最小的长度都是1,即:子列表中至少含有一个元素。
好了,说完这些,下面是具体的实现了:
#!usr/bin/env python
#encoding:utf-8
from __future__ import division
'''
__Author__:沂水寒城
功能:寻找平衡点
'''
def find_balance_point(numbers):
'''
网上的代码,寻找平衡点
来源于:http://blog.renren.com/share/235087438/3004327956
测试数据:numbers = [1,3,5,7,8,2,4,20]
缺点:你可以交换列表中的数据可以发现结果错误,可能正是他们的对于
平衡点的定义不同,都按照简单版本的来了
'''
total=sum(numbers)
fore=0
for number in numbers:
if fore<(total-number)/2:
fore+=number
else:
break
if fore == (total-number)/2:
print number
else:
print r'not found'
def split_list(num_list):
'''
输入一个列表,判断是否可以划分为大小相等的两个子列表,可以返回True不可以返回False
'''
total=sum(num_list)
half=total/2
if int(half)!=half:
return False
else:
all_sub_list=get_list_all_sub_list(num_list)
i=0
flag=False
while i<len(all_sub_list):
one_list=all_sub_list[i]
two_list=[one for one in num_list if one not in one_list]
if sum(one_list)==sum(two_list):
flag=True
break
else:
i+=1
if flag:
return True
else:
return False
def main_func(num_list):
'''
输入一个列表判断是否存在平衡点
'''
res=False
for i in range(len(num_list)):
temp_list=num_list[:]
flag=temp_list.pop(i)
if split_list(temp_list):
res=True
print '平衡点为:', flag
if not res:
print '不存在平衡点!!!'
def get_list_all_sub_list(num_list):
'''
输入一个列表,返回该列表所有的子列表,这里定义的空列表不属于子列表,故:子列表最小长度为1
'''
if len(num_list)==1:
return [num_list]
sub_list=get_list_all_sub_list(num_list[:-1])
extra=num_list[-1:]
temp_list=[]
for one in sub_list:
temp_list.append(one+extra)
return sub_list+temp_list
if __name__ == '__main__':
num_list=[1,3,2,4,5,7,8,20]
num_list2=[1,3,2,4,5,7,8,200,9000,300000]
print '*********************************网上代码测试*********************************'
find_balance_point(num_list)
find_balance_point(num_list2)
print '*********************************自己的代码测试*********************************'
main_func(num_list)
print '------------------------------------------------------------------------------------'
main_func(num_list2)
结果如下:
*********************************网上代码测试*********************************
not found
not found
*********************************自己的代码测试*********************************
平衡点为: 2
平衡点为: 4
平衡点为: 8
平衡点为: 20
------------------------------------------------------------------------------------
不存在平衡点!!!
为了进一步检验得到的平衡点是否真的是自己给出来定义的平衡点这里打印出来,每个平衡点分割出来的两个子列表:
[1, 3, 5, 7, 8] [4, 20]
平衡点为: 2
[1, 2, 5, 7, 8] [3, 20]
平衡点为: 4
[1, 20] [3, 2, 4, 5, 7]
平衡点为: 8
[1, 3, 2, 4, 5] [7, 8]
平衡点为: 20
可以看到:在每个平衡点下面的两个字列表的确是和相等的,从而验证正确