原题:有一序列a,b,大小均为n,序列元素的值任意整型数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小,用python写。
偶尔看到网上有关于上述题目的各种解答,但都有各种反例存在。在查看了一些程序代码,并仔细研究了本题后,发现在考虑情况时,总会漏掉一些情况,导致出现各种反例不满足。
本程序从集合的角度出发,完美解决了题目的要求,不但可以比较两个长度相等的序列,还可以比较长度不相等的序列(代码后面附有截图),但并不是通过交换元素进行的,希望其他人,能通过本程序受到启发,进一步以题目要求的方式进行编写,本程序可帮助你进行验证自己的程序是否正确。
程序编写使用的为Python3,如有无法正常运行,请检查你所复制的代码是否有误。
import itertools
import random
def min_diff(*args, length_of_list=4):
if not args:
# 产生随机序列,并且不会出现重复元素
# 给出a, b, 以及对c排序(后面会用到c的顺序)
c = []
while len(c) < length_of_list:
num = random.randint(1, 100)
if num not in c:
c.append(num)
a = c[:len(c) // 2]
b = c[len(c) // 2:]
else:
try:
a = list(args[0])
b = list(args[1])
c = a + b
except TypeError:
print('请检查你的输入是否正确!')
return None
if len(a) != len(b):
flag = False
else:
flag = True
c.sort()
# 产生c的除空集和其本身之外的所有子集,并转换成列表
# 例 [[3], [19], [51], [3, 19], [3, 51], [19, 51]]
a_list = []
for i in range(1, len(c)):
d = list(itertools.combinations(c, i))
for e in d:
a_list.append(list(e))
# 得到交换a,b中元素后的所有情形
# 如果函数参数为奇数,则代码 'and len(ae_min) == len(ae_max)' 必须删除,否则报错
a_sum = []
if flag:
for ae_min in a_list:
for ae_max in a_list:
if sorted(ae_min + ae_max) == c and len(ae_min) == len(ae_max):
a_sum.append(ae_min)
a_sum.append(ae_max)
else:
for ae_min in a_list:
for ae_max in a_list:
if sorted(ae_min + ae_max) == c:
a_sum.append(ae_min)
a_sum.append(ae_max)
finally_list = a_sum[:len(a_sum) // 2]
# 分别计算每一种情形的a序列和与b序列和之差,列表形式
finally_sum = []
for j in range(0, len(a_sum) // 2, 2):
abs_value = abs(sum(a_sum[j]) - sum(a_sum[j + 1]))
finally_sum.append(abs_value)
# 获取a序列和与b序列和之差的最小值的所有索引
index_list = []
for k in enumerate(finally_sum):
if k[1] == min(finally_sum):
index_list.append(k[0])
print('a: {}\nb: {}'.format(a, b))
print('一共有{}对满足条件的组合:\nThe minimal diff: {}'.format(len(index_list), min(finally_sum)))
for m in index_list:
if sum(finally_list[m * 2]) < sum(finally_list[m * 2 + 1]):
finally_list[m * 2], finally_list[m * 2 + 1] = finally_list[m * 2 + 1], finally_list[m * 2]
print('{}\nmax_list: {}, max_sum: {}'.format('=' * 40, finally_list[m * 2], sum(finally_list[m * 2])))
print('min_list: {}, min_sum: {}'.format(finally_list[m * 2 + 1], sum(finally_list[m * 2 + 1])))
if __name__ == '__main__':
list1 = [1, 2]
list2 = [3, 4]
min_diff(list1, [82, 55])
print()
min_diff(length_of_list=6)
下面贴上本程序运行的一些结果:
2017-11-29-2024.jpg 2017-11-29-2026.jpg
网友评论