背包经典问题01:给一个整数的集合,要把它分成两个集合,要两个集合的数的和最接近
**在没有百度的情况下,自己思考想出来的解决办法,如下,初学算法(哈哈)**
代码思路:
- 把集合分成两个,随便分,不用刻意分成数量相等的两个数组,记为num1,num2
- 分别计算两个数组的数的和,记为num1_all,num2_all
- 创建一个循环,比较num1_all和num2_all的差值,记为cha
- 用num1数组中的第一个数和num2中第一个数相减,记为sum_dif,再和cha进行比较,如果比cha小,那个就交换这两个数,在用num1的第一个和num2第二个相减…直到交换一个数再也没法缩短两个数组的差距。
- 上一步只交换一个数,那么现在就要考虑1个交换多个和多个交换多个,直到num1和num2差距为0或1,或者直到循环完。
- 结束了,此时两个数组相差最小
话不多说,直接上代码:
import random
def she_num():
all_num_list = []
for i in range(0,51):
#填充随机数
all_num_list.append(random.randint(1,1000))
num1 = []
num2 = []
print(all_num_list)
num1_all = 0
num2_all = 0
#为了方便就把两个数组分为差不多长的
for i in range(0,len(all_num_list)):
if i < int(len(all_num_list)/2):
num1.append(all_num_list[i])
#计算和
num1_all += all_num_list[i]
else:
num2.append(all_num_list[i])
#计算和
num2_all += all_num_list[i]
if num1_all - num2_all > 1 or num2_all - num1_all > 1:
currect_i = 0
currect_j = 0
#第一个数组交换数的数量,默认从一个数开始
number_1 = 1
#第二个数组交换数的数量
number_2 = 1
cha_one = True
print(num1_all)
print(num2_all)
while True:
#每次循环可以调用一下排序,不调用也不影响
#num1.sort()
#num2.sort()
#计算差值
cha = int(num1_all - num2_all)
#判断哪个数组比较大
if cha > 1:
if cha_one:
cha_one = False
currect_i = 0
currect_j = 0
number_1 = 1
number_2 = 1
sum1 = 0
sum2 = 0
#计算第一个数组需要交换的数的和
for i in range(0,number_1):
sum1 +=num1[currect_i + i]
#计算第二个数组需要交换的数的和
for i in range(0,number_2):
sum2 += num2[currect_j + i]
#计算差值
sum_dif = sum1 - sum2
#判断差值是否大于0,并且小于总的差值,如果满足条件就交换
if sum_dif > 0 and sum_dif < cha:
exchange(num1,num2,currect_i,currect_j,number_1,number_2)
num1_all -= int(sum_dif)
num2_all += int(sum_dif)
currect_j +=1
#判断是否超过数组长度
if currect_j + number_2 > len(num2) - 1:
currect_i +=1
currect_j = 0
if currect_i + number_1 > len(num1) - 1:
currect_j = 0
currect_i = 0
number_2 +=1
if number_2 > len(num2) - 1:
number_2 = 1
number_1 +=1
if number_1 > len(num1) - 1:
break
#下面的代码其实不是必须的,只要最开始时保证第一个数组总和比第二个数组大,下面的代码就没用了,但是在不知道两个数组那个的和比较大的情况下,还是需要的
elif cha < -1:
if not cha_one:
cha_one = True
currect_i = 0
currect_j = 0
number_1 = 1
number_2 = 1
sum1 = 0
sum2 = 0
for i in range(0, number_1):
sum1 += num1[currect_i + i]
for i in range(0, number_2):
sum2 += num2[currect_j + i]
sum_dif = sum2 - sum1
if sum_dif > 0 and sum_dif < -cha:
exchange(num1, num2, currect_i, currect_j, number_1, number_2)
num2_all -= int(sum_dif)
num1_all += int(sum_dif)
currect_i += 1
if currect_i + number_1 > len(num1) - 1:
currect_j += 1
currect_i = 0
if currect_j + number_2 > len(num2) - 1:
currect_j = 0
currect_i = 0
number_1 += 1
if number_1 > len(num1) - 1:
number_1 = 1
number_2 += 1
if number_2 > len(num2) - 1:
break
elif cha <= 1 or cha >=-1:
break
print('数组1:')
print(num1)
print('数组2:')
print(num2)
print('数组1所有数的和:')
print(num1_all)
print('数组2所有数的和:')
print(num2_all)
"""
exchange函数功能:交换两个数组的数
num1:第一个数组
num2:第二个数组
num1_start:第一个数组起始点
num2_start:第二个数组起始点
num1_num:第一个数组交换数量
num2_num:第二个数组交换数量
"""
def exchange(num1,num2,num1_start,num2_start,num1_num,num2_num):
exc1 = list(num1[num1_start:num1_start + num1_num])
exc2 = list(num2[num2_start:num2_start + num2_num])
print("num1 ->> num2:")
print(exc1)
print("num2 ->> num1:")
print(exc2)
print('++++++++++++++')
for i in range(num1_start,num1_start + num1_num):
num1.pop(num1_start)
for i in range(num2_start,num2_start + num2_num):
num2.pop(num2_start)
num1 += exc2
num2 += exc1
return 0
if __name__ == "__main__":
she_num()