鱼C论坛

 找回密码
 立即注册
查看: 6028|回复: 44

[已解决]鱼C论坛python挑战赛(01期)

[复制链接]
发表于 2017-6-15 19:08:47 | 显示全部楼层 |阅读模式
100鱼币
本帖最后由 jerryxjr1220 于 2017-7-7 16:55 编辑

Python的编程技能还是要靠平时不断地练习才能提高,为了提高大家的积极性,特别设立了这个挑战赛,希望大家多多参与!

第一个解答本题的鱼油奖励100鱼币,本期挑战赛限时3天,截至日:6月18日24时,参赛人员:python论坛任何人员(包括版主)。

另外,如果有创意的解题方法或者优雅的代码,会酌情追加奖励!

本期题目:

给定一个列表L,例如:['ACBD','ADBC','CBDD','CABD'],包含有n组字符串。

通过下图,可以发现,最后一行的字符串包含了列表L中所有字符串,也就是说L中所有字符串都是最后一行字符串的“子字符串”(未必连续),这最后一行字符串称作为“母字符串”。


  1. A C    B D
  2. A        D B C
  3.    C   B D    D
  4.    C A B D
  5. ===============
  6. A C A B D B C D
复制代码


现在请通过给定的列表L,求出最短的包含L中所有字符串的“母字符串”的长度。

例如:
L = ['ACBD','ADBC','CBDD','CABD']
输出:8

@冬雪雪冬 @SixPy @~风介~

感谢小甲鱼老师倾情赞助!

本期挑战结束,挑战结果见http://bbs.fishc.com/thread-89179-1-1.html

本界挑战赛,共设5场比赛,每周安排1~2场,每场挑战赛为期3天,每场比赛奖励100鱼币,同时会给优秀代码增加额外奖励!

02期即将开始,欢迎大家踊跃参与!
最佳答案
2017-6-15 19:08:48
  1. def combinations(rawList):
  2.     AllRoads = [[rawList, '']]

  3.     oldMaps = set()
  4.    
  5.     while 1:
  6.         tempAllRoads = []
  7.         
  8.         for t in AllRoads:
  9.             currentWords = {i[0] for i in t[0] if i}

  10.             for j in currentWords:
  11.                 # 字符串不需要深拷贝。
  12.                 copyList = t[0].copy()
  13.                
  14.                 for index, data in enumerate(copyList):
  15.                     if data:
  16.                         if data[0] == j:
  17.                             copyList[index] = data[1:]

  18.                 strs = ''.join(copyList)

  19.                 if len(strs) == 1:
  20.                     return t[1]+j+strs
  21.                
  22.                 if strs not in oldMaps:
  23.                     tempAllRoads.append([copyList, t[1]+j])

  24.                 oldMaps.add(strs)

  25.         AllRoads = tempAllRoads
复制代码


优化版本。基本思路是根据 广度优先算法来的。

最佳答案

查看完整内容

优化版本。基本思路是根据 广度优先算法来的。

评分

参与人数 3荣誉 +21 鱼币 +115 贡献 +21 收起 理由
康小泡 + 10 + 10 + 10 质量帖
冬雪雪冬 + 5 + 5 + 5 想了半天也没有解题的头绪,看看下一题我会.
小甲鱼 + 6 + 100 + 6 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-15 19:08:48 | 显示全部楼层    本楼为最佳答案   
  1. def combinations(rawList):
  2.     AllRoads = [[rawList, '']]

  3.     oldMaps = set()
  4.    
  5.     while 1:
  6.         tempAllRoads = []
  7.         
  8.         for t in AllRoads:
  9.             currentWords = {i[0] for i in t[0] if i}

  10.             for j in currentWords:
  11.                 # 字符串不需要深拷贝。
  12.                 copyList = t[0].copy()
  13.                
  14.                 for index, data in enumerate(copyList):
  15.                     if data:
  16.                         if data[0] == j:
  17.                             copyList[index] = data[1:]

  18.                 strs = ''.join(copyList)

  19.                 if len(strs) == 1:
  20.                     return t[1]+j+strs
  21.                
  22.                 if strs not in oldMaps:
  23.                     tempAllRoads.append([copyList, t[1]+j])

  24.                 oldMaps.add(strs)

  25.         AllRoads = tempAllRoads
复制代码


优化版本。基本思路是根据 广度优先算法来的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-15 22:03:57 | 显示全部楼层
大家踊跃答题哦,可以提供一些思路,未必肯定正确,供大家参考。
如果把L中的字符串全部连起来构成的“母字符串”肯定包含所有“子字符串”,但是未必最短。
然后可以想办法删除“母字符串”中的字符,看哪些字符删除后,“母字符串”依然成立,以此来缩短“母字符串”的长度。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-15 22:22:23 | 显示全部楼层
可不可以调整L里面字符串的顺序呢?比如变成C开头,这个好像没有说清楚。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-15 22:26:38 | 显示全部楼层
ooxx7788 发表于 2017-6-15 22:22
可不可以调整L里面字符串的顺序呢?比如变成C开头,这个好像没有说清楚。

列表L里面的n个字符串在L中的位置可以调整,也就是可以对L进行sort()操作,不会影响最后结果。
但是这些字符串中的字母顺序是不能改变的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-15 22:34:09 | 显示全部楼层
再给一些提示,我写了一个判断子字符串s是否在母字符串strings中的函数,当然,这仅供参考,未必一定有用。
  1. def is_sub(s, strings):
  2.     if len(s) == 1 and s in strings:
  3.         return True
  4.     if s[0] not in strings:
  5.         return False
  6.     return is_sub(s[1:], strings[strings.find(s[0])+1:])
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-16 13:04:05 From FishC Mobile | 显示全部楼层
大家加油!100鱼币在向你招手!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-16 15:07:21 | 显示全部楼层
jerryxjr1220 发表于 2017-6-16 13:04
大家加油!100鱼币在向你招手!

早就写好了,不想发,怕影响其他人的思路。
等等看~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-16 18:59:04 | 显示全部楼层
你这题难度有点高啊,曲高和寡~

类似这种有奖竞答的题目,鱼币应该由论坛出吧,不应该由出题者支出。
@小甲鱼 @康小泡 @~风介~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-16 19:33:10 From FishC Mobile | 显示全部楼层
SixPy 发表于 2017-6-16 18:59
你这题难度有点高啊,曲高和寡~

类似这种有奖竞答的题目,鱼币应该由论坛出吧,不应该由出题者支出。

谁出鱼币无所谓的,反正我有好多鱼币也用不掉,无非是提高一点大家的积极性!
这次是第一期,题目难度还需要摸索,怕太简单,几分钟就被解决了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-16 20:09:47 | 显示全部楼层
  1. L = ['ACBD','ADBC','CBDD','CABD']
  2. result = []

  3. def check(l):
  4.     for each in l:
  5.         if each != '':
  6.             return False
  7.     return True

  8. def poplist(l):
  9.     x = []
  10.     for each in l:
  11.         if each != '':
  12.             x.append(each[0])
  13.     x = list(set(x))
  14.     x.sort()
  15.     return x

  16. def dele(l, x):
  17.     y = [ ]
  18.     for each in l:
  19.         if each == '':
  20.             y.append(each)
  21.         else:
  22.             if each[0] == x:
  23.                 y.append(each[1:])
  24.             else:
  25.                 y.append(each)
  26.     return y


  27. def dfs(step, l):
  28.     if check(l):
  29.         result.append(step)
  30.         return
  31.     x = poplist(l)
  32.     for each in x:
  33.         lx = dele(l, each)
  34.         dfs(step+1, lx)
  35.         
  36. dfs(0, L)
  37. print(min(result))
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +2 收起 理由
jerryxjr1220 + 5 + 5 + 2 答题奖励!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-16 21:01:16 | 显示全部楼层

L = ['AhCBDk','ADBekC','eCBDgD','CABghD']

用你的程序试试这个~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 00:15:39 | 显示全部楼层
SixPy 发表于 2017-6-16 18:59
你这题难度有点高啊,曲高和寡~

类似这种有奖竞答的题目,鱼币应该由论坛出吧,不应该由出题者支出。

我记得数据结构课程里面好像有这个题目来着,只是忘记了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 02:41:50 | 显示全部楼层
心累啊,方法有点笨,接近十二个小时
丫的,今天还要考四级,要是得不到这100鱼币,我就要崩溃了。

  1. # 基列表挑选准则:挑选含不同字母多的字符串
  2. def base(a):
  3.     c = []
  4.     for i in range(len(a)):
  5.         c.append(len(set(a[i])))
  6.     return (c.index(max(c))) #返回符合要求的字符串在列表中的位置

  7. # 次列表的挑选准则:挑选字母在基列表中位置靠前的字符串,如果没有则选择第一个字符串
  8. def less(a,a_base):
  9.     if len(a) == 1:
  10.         return 0
  11.     else:
  12.         temp = []
  13.         for i in a_base:
  14.             for j in range(len(a)):
  15.                 try:
  16.                     temp.append(a[j].index(i))
  17.                 except ValueError:
  18.                     temp.append(len(a[j]))
  19.             if min(temp)<len(a[j]):
  20.                 return(temp.index(min(temp))) #返回符合要求的字符串在列表中的位置
  21.         return 0 #如果没有与基列表重复的字母,则选择第一个字符串

  22. # 寻找所有的匹配组合,返回匹配超度最长的组合。
  23. def seek_index(a_base,a_less):
  24.     #返回在主列表中的位置T=[组合1,..,组合n] 组合1=[位置0,...,位置n]
  25.     T = []
  26.     for i in range(len(a_less)):
  27.         temp = []        
  28.         for j in range(i,len(a_less)):
  29.             if temp==[]:
  30.                 k=0
  31.             try:
  32.                 k = a_base.index(a_less[j],k)
  33.                 temp.append(k) #偶数位置是对应元素在基列表中的位置
  34.                 temp.append(j) #奇数位置是对应元素在次列表中的位置
  35.                 k += 1
  36.             except ValueError:
  37.                 pass
  38.             
  39.         T.append(temp)
  40.     #返回最长组合
  41.     temp = []
  42.     for k in T:        
  43.         temp.append(len(k))
  44.     return (T[temp.index(max(temp))])

  45. #利用得到的最优匹配位置进行匹配,在基列表中插入不满足次列表的元素
  46. def match(a_base,a_less,index):

  47.     temp_base = []
  48.     temp_less = []
  49.     for i in range(len(index)):
  50.         if not i % 2:
  51.             temp_base.append(index[i])#得到对应元素在基列表中的位置
  52.         else:
  53.             temp_less.append(index[i])#得到对应元素在次列表中的位置

  54.     for i in range(len(temp_less)):
  55.         if temp_less[i] != 0:
  56.             if i == 0:
  57.                 temp = a_less[:temp_less[i]]
  58.                 temp.reverse()
  59.                 for j in range(len(temp)):
  60.                     a_base.insert(temp_base[i],temp[j])
  61.             elif i != len(a_less) - 1 and temp_less[i] - temp_less[i-1] > 1:
  62.                 temp = a_less[temp_less[i-1]+1:temp_less[i]]
  63.                 temp.reverse()
  64.                 for j in range(len(temp)):
  65.                     a_base.insert(temp_base[i],temp[j])
  66.             elif i == len(temp_less) -1 and i != len(a_less) - 1 and temp_less[i] - temp_less[i-1] == 1:
  67.                 temp = a_less[temp_less[i]+1:]
  68.                 for j in range(len(temp)):
  69.                     a_base.append(temp[j])

  70.     return a_base            
  71.         
  72.    
  73. L = ['ACBD','ADBC','CBDD','CABD']

  74. list_base = list(L[base(L)]) # 挑选基列表
  75. L.remove(''.join(list_base)) # 在L中移除选中的基列表所对应的字符串

  76. for i in range(len(L)):
  77.     list_less = list(L[less(L,list_base)]) #挑选次列表
  78.     L.remove(''.join(list_less))# 在L中移除选中的次列表中对应的字符串
  79.     nice_index = seek_index(list_base,list_less) #查找最佳匹配顺序
  80.     list_base = match(list_base,list_less,nice_index) #进行匹配   


  81. print (len(list_base))




  82.                






























复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 02:44:55 | 显示全部楼层
SixPy 发表于 2017-6-16 21:01
L = ['AhCBDk','ADBekC','eCBDgD','CABghD']

用你的程序试试这个~
  1. ['A', 'h', 'e', 'C', 'A', 'g', 'h', 'B', 'D', 'B', 'e', 'k', 'g', 'D']
  2. 14
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 03:27:38 | 显示全部楼层
SixPy 发表于 2017-6-16 18:59
你这题难度有点高啊,曲高和寡~

类似这种有奖竞答的题目,鱼币应该由论坛出吧,不应该由出题者支出。

嗯嗯,可以的,支持此类互动!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 03:29:09 | 显示全部楼层
jerryxjr1220 发表于 2017-6-15 22:03
大家踊跃答题哦,可以提供一些思路,未必肯定正确,供大家参考。
如果把L中的字符串全部连起来构成的“母 ...

支持楼主,可以创建一个淘专辑,将此类活动汇集起来,方便后来者学习~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-17 06:23:21 From FishC Mobile | 显示全部楼层
小甲鱼 发表于 2017-6-17 03:29
支持楼主,可以创建一个淘专辑,将此类活动汇集起来,方便后来者学习~

感谢老大支持!
挑战结果会在挑战期限之后公布,同时会归类到淘专辑
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-17 06:26:16 From FishC Mobile | 显示全部楼层
Teagle 发表于 2017-6-17 02:44

你再看看,好像你的母字符串并没有全部包含子字符串哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 07:46:21 | 显示全部楼层
jerryxjr1220 发表于 2017-6-17 06:26
你再看看,好像你的母字符串并没有全部包含子字符串哦

怎么可能没有呢
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 21:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表