Python程序设计之列表划分为二后作差(求子列表差值最小的问题)

(1)问题描述:
一个含偶数个元素的列表如[1,2,3,4],将其划分为两个子列表,如[1,2]和[3,4],两者分别求和然后作差为(大的值减去小的值)(3+4)-(1+2)=4,但是4不是列表划分的最小差值,最小差值为(4+1)-(3+2)=0,问题就是求最下差值和划分的列表。
(2)实现过程如下:
1.关于列表的划分,设列表长度为n(n为偶数),划分为长度为(n//2)的两个子列表:
①先求阶层

#表示从m个元素中选择n个元素,随机选择(无序)
def qiujieceng(n,m):
    a,b,c,d=1,1,n,m
    for i in range(c+1,d+1):
        a*=i
    for i in range(1,c+1):
        b*=i
    return a//b
#有序选择
def qiujieceng2(n,m):
    a,c,d=1,n,m
    for i in range(c+1,d+1):
        a*=i
    return a    

测试代码:

print(qiujieceng(3,6),end='\n')
print(qiujieceng2(3,6),end='\n')

结果:

20
120

②通过random模块的sample()函数完成在列表中选择随机数

#从长度为n的列表中随机取m个元素,将取出的m个元素重新赋值给一个list,返回列表list
def huafen(m,n):
    list=[]
    #list1=[]
    w=qiujieceng2(n,len(m))#表示要划分的次数
    #print(w,'helllo')
    q=0
    for i in range(qiujieceng2(n,len(m))):
        while q < w:
            list1=random.sample(m,len(m)//2)#将列表m划分为长度为len(m)//2的子列表
            if list1 not in list:
                list.append(list1)
                q+=1
    return list

测试如下:

print(huafen([6,2,3,4],2),end='\n')

结果:

[[4, 6], [4, 2], [2, 6], [6, 2], [3, 2], [6, 4], [6, 3], [4, 3], [3, 4], [3, 6], [2, 4], [2, 3]]

2.根据sum=a+b,b=sum-a=>min(a-b)=min(sum-2b)=>求符合条件的b的最大值,来求最小差值问题:

def minlist(list,n):
    su=sum(list)//2
    mi=[]
    ma=[]
    maxx=0
    print('对被减b求和需要小于等于:',su,end='\n')
    list1=huafen(list,n)
    print(list1)
    for i in range(len(list1)):
        if sum(list1[i])<=su:
            if list1[i]==su:
                ma.append(list1[i])
            else:
                mi.append(list1[i])
    if len(ma)!=0:
        print('将', list, '划分为', ma, '中的任意一个子列表时,与列表剩余元素之和的差为最小值时,为:',sum(list) - 2*sum(ma[0]), end='\n')
    else:
        for i in range(len(mi)):
            if sum(mi[i])>maxx:
                maxx=sum(mi[i])
        #print([l for l in mi if sum(l)==maxx],end='\n')
        le=[l for l in mi if sum(l) == maxx]
        print('将',list,'划分为',[l for l in mi if sum(l)==maxx],'中的任意一个子列表时,与列表剩余元素之和的差为最小值,为',sum(list)-2*sum(le[0]),end='\n')

测试代码:

t=[1,7,10,8,4,6]
#[t.append(random.randint(1,10)) for i in range(4)]
minlist(t,len(t)//2)

结果如下:

[1, 7, 10, 8, 4, 6] 划分为 [[6, 8, 4], [1, 10, 7], [7, 10, 1], [10, 1, 7], [4, 6, 8], [8, 6, 4], [4, 8, 6], [6, 4, 8], [8, 4, 6], [7, 1, 10], [10, 7, 1], [1, 7, 10]] 中的任意一个子列表时,与列表剩余元素之和的差为最小值,为 0

3.问题分析:
目前代码只能实现无重复元素的列表的划分:
源代码链接:
https://download.csdn.net/download/qxyloveyy/12222034

学习笔记

1.是否可以通过内置函数和列表推导公式来实现列表的划分(尚且未知);
2.关于求列表划分阶乘时,是否可以通过列表推导来实现(未知);
3.如果列表元素重复,while循环的退出语句应该是什么(未知);
4.通过random模块的函数可以实现随机存取;

发布了78 篇原创文章 · 获赞 83 · 访问量 5408

猜你喜欢

转载自blog.csdn.net/qxyloveyy/article/details/104651763
今日推荐