鱼C论坛

 找回密码
 立即注册
查看: 8709|回复: 23

[技术交流] Python:每日一题 42

[复制链接]
发表于 2017-5-10 15:47:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ooxx7788 于 2017-5-11 09:18 编辑

难一点的题目翻译题目太长了,今天出个简单一些的吧。
文字回文联
要求:
1、给定字符串是不能改动。
2、生成的回文联应当尽量短。
3、当有多种可能的情况时,给定文字处于起始位置的优先。列入例子中的,ab。当然bab也是结果,但是因为aba中ab处于开始位置,所以aba优先。
  1. makePalindrome('a') --> 'a'
  2. makePalindrome('ab') --> 'aba'
  3. makePalindrome('abc') --> 'abcba'
  4. makePalindrome('race') --> 'racecar'
  5. makePalindrome('leveled') --> 'deleveled'                #注意哦,这个策略有点不一样的哦。
复制代码


测试代码:
  1. test.assert_equals(makePalindrome('ab'), 'aba');
  2. test.assert_equals(makePalindrome('abb'), 'abba');
  3. test.assert_equals(makePalindrome('abc'), 'abcba');
  4. test.assert_equals(makePalindrome('rad'), 'radar');
  5. test.assert_equals(makePalindrome('race'), 'racecar')
复制代码


本题冬雪的答案已然很简单了,所以我就给个链接吧!
http://bbs.fishc.com/forum.php?mod=redirect&goto=findpost&ptid=87034&pid=2886595

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-5-10 17:01:09 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 17:01:25 From FishC Mobile | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-5-10 17:02 编辑

没理解题目,要去处重复?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 17:10:38 | 显示全部楼层
jerryxjr1220 发表于 2017-5-10 17:01
没理解题目,要去处重复?

生成回文联
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-10 17:25:28 | 显示全部楼层
jerryxjr1220 发表于 2017-5-10 17:01
没理解题目,要去处重复?

不要去重复,要保留原有的字符串。
在原有的字符串加工成回文。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 17:46:42 From FishC Mobile | 显示全部楼层
主要不理解的是如果ab的回文是aba, 那么leveled的回文怎么可以deleveled?
如果这个可以,那么ab生成bab应该也可以啊?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-10 17:53:03 | 显示全部楼层
jerryxjr1220 发表于 2017-5-10 17:46
主要不理解的是如果ab的回文是aba, 那么leveled的回文怎么可以deleveled?
如果这个可以,那么ab生成bab应 ...

是可以啊,但是还有第3条要求啊。
  1. 3、当有多种可能的情况时,给定文字处于起始位置的优先。列入例子中的,ab。当然bab也是结果,但是因为aba中ab处于开始位置,所以aba优先。
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 17:56:01 From FishC Mobile | 显示全部楼层
ooxx7788 发表于 2017-5-10 17:53
是可以啊,但是还有第3条要求啊。

就是要生成从头循环的和从尾循环的,再比较那个循环短,一样短的再优先取从头循环的?
逻辑是这样?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-10 18:12:35 | 显示全部楼层
本帖最后由 ooxx7788 于 2017-5-10 18:16 编辑
jerryxjr1220 发表于 2017-5-10 17:56
就是要生成从头循环的和从尾循环的,再比较那个循环短,一样短的再优先取从头循环的?
逻辑是这样?


我认为是这样吧。
其实题目的难点,我认为是在于如果给定单词部分存在可以形成回文的结构,如何判定并利用这个回文结构。
而普通单词必然是在最后一个字母后面接一段前文翻转最短。
例如level本身就是回文词,leveled就要在这个基础上利用回文。
class,ss本身也是回文结构,所以要返回classalc。
popular,pop本身是回文结构,所以要在这个回文的基础上反转,变成ralupopular。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 20:06:11 | 显示全部楼层
先判断字符串中有无回文部分,如果有利用次部分,但回文部分只能在两端才有用。
  1. def makePalindrome(string):
  2.     for i in range(len(string), 1, -1):
  3.         if string[:i] == string[i - 1::-1]:
  4.             return string[: i - 1: -1] + string
  5.     for i in range(-len(string), -1):
  6.         if string[i:] == string[:i - 1:-1]:
  7.             return string + string[i - 1::-1]
  8.     return string + string[-2::-1]

复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
ooxx7788 + 1 + 1 你为什么那么强呢?+1分

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 20:53:12 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-5-10 21:01 编辑
ooxx7788 发表于 2017-5-10 18:12
我认为是这样吧。
其实题目的难点,我认为是在于如果给定单词部分存在可以形成回文的结构,如何判定并 ...

  1. def get_string(string):
  2.     sub = ''
  3.     for i in range(1, len(string)):
  4.         if string[:i + 1] == string[i:2 * i + 1][::-1]:
  5.             sub = string[:i]
  6.     if sub != '':
  7.         newstring = string[len(sub):]
  8.     else:
  9.         newstring = string
  10.     return newstring

  11. def recycle(string):
  12.     newstring = get_string(string)
  13.     newstring = newstring[::-1] + newstring[1:]
  14.     newantstring = get_string(string[::-1])[::-1]
  15.     newantstring = newantstring + newantstring[:-1][::-1]
  16.     if len(newstring) < len(newantstring):
  17.         return newstring
  18.     else:
  19.         return newantstring

  20. print(recycle('popular'))
复制代码


按照这个逻辑写的,没有验证过
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-10 20:57:56 | 显示全部楼层
jerryxjr1220 发表于 2017-5-10 20:53
按照这个逻辑写的,没有验证过
  1. print(recycle('abb'))
  2. abbba
复制代码

不对哟
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 21:24:22 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-5-10 21:30 编辑


嗯,我只判断了奇数位的回文,还有偶数位的回文漏了

版主的代码比较简洁 ,那我的就不写了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 22:19:59 | 显示全部楼层
冬雪雪冬 发表于 2017-5-10 20:06
先判断字符串中有无回文部分,如果有利用次部分,但回文部分只能在两端才有用。

摩拜单车
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 23:28:42 | 显示全部楼层
本帖最后由 当回首遇上转身 于 2017-5-10 23:35 编辑

最后一个还没解决,先发着占楼先
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-

  3. '''
  4. Created on 2017.05.10 20:17
  5. @author: 当回首遇上转身
  6. '''


  7. def a_mix(shuru):
  8.     a = []
  9.     shuchu = ''
  10.     for i in range(len(shuru)):
  11.         if shuru[len(shuru)-1-i:len(shuru)-i] != shuru[len(shuru)-1]:
  12.             while i != len(shuru):
  13.                 a.append(shuru[len(shuru)-1-i:len(shuru)-i])
  14.                 i += 1
  15.             break
  16.     a.insert(0,shuru)
  17.     for each in a:
  18.         shuchu += each
  19.     return shuchu

  20. def makePalindrome(shuru2):
  21.     b = []
  22.     shuru1 = ''
  23.     for i in range(len(shuru2)):
  24.         shuru1  = shuru1 + (shuru2[len(shuru2)-1-i:len(shuru2)-i])

  25.     a2 = a_mix(shuru1)
  26.     a1 = a_mix(shuru2)
  27.     print("'",end = '')
  28.     if len(a1) > len(a2):
  29.         print(a2,end = '')
  30.         
  31.     else:
  32.         print(a1,end='')
  33.     print("'")

  34. makePalindrome('race')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-11 00:50:34 | 显示全部楼层
本帖最后由 当回首遇上转身 于 2017-5-11 07:07 编辑

没错,我又回来了
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-

  3. '''
  4. Created on 2017.05.10 20:17
  5. @author: 当回首遇上转身
  6. '''

  7. def Input_mix(shuru1,shuru2):
  8.     shuchu = ''
  9.     for k in range(len(shuru1)):
  10.         if shuru1[len(shuru1)-1-k:] == shuru2[:k+1]:
  11.             j = (len(shuru1)-1-k)
  12.         k += 1
  13.     shuchu = shuru1[:j] + shuru2
  14.     return shuchu

  15. def makePalindrome(shuru):
  16.     shuru1 = ''
  17.     for i in range(len(shuru)):
  18.         shuru1  += (shuru[len(shuru)-1-i:len(shuru)-i])

  19.     a2 = Input_mix(shuru1,shuru)
  20.     a1 = Input_mix(shuru,shuru1)
  21.     print("输出字符为:'",end = '')
  22.     if len(a1) > len(a2):     
  23.         print(a2,end = '')
  24.     else:
  25.         print(a1,end = '')
  26.     print("'")

  27. while 1:
  28.     Input = input("请输入字符:")
  29.     makePalindrome(Input)
复制代码

用了好多局部变量有点乱别见怪,逻辑是这样没办法

程序输出:
  1. ====== RESTART: C:\Users\Tony\OneDrive\文档\practice\2017.05.10\huiwen.py ======
  2. 请输入字符:a
  3. 输出字符为:'a'
  4. 请输入字符:ab
  5. 输出字符为:'aba'
  6. 请输入字符:abc
  7. 输出字符为:'abcba'
  8. 请输入字符:race
  9. 输出字符为:'racecar'
  10. 请输入字符:leveled
  11. 输出字符为:'deleveled'
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-1 18:24:30 | 显示全部楼层
从0开始到n-1,逐步缩短字符串,找出往前回文和往回后文的边界,
输出最先找到的(最短)
  1. # 正反两个方向循环切片判断回文边界,至少切边长度为1时成立,根据边界拼接最短的
  2. def makePalindrome(s):
  3.     """最短回文制造器,为您的输入s制造回文"""
  4.     i = 0
  5.     while 1:
  6.         if s[i:] == s[i:][::-1]:
  7.             axis = i
  8.             break
  9.         elif s[:-i] == s[:-i][::-1] and s[:i]:
  10.             axis = -i
  11.             break
  12.         i += 1
  13.     # 哪边短就往哪边加切片
  14.     out = s+s[:i][::-1] if axis>=0 else s[-i:][::-1]+s
  15.     return out
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-6 17:20:36 | 显示全部楼层
本帖最后由 shigure_takimi 于 2017-12-6 17:26 编辑
  1. def isP(s): # 判断是否回文
  2.     return s[::-1] == s  

  3. def makePalindrome(s):
  4.     if isP(s):  # 如果参数本身回文,返回其本身
  5.         return s
  6.     else:
  7.         p = [] # 存储左看、右看最大回文位置
  8.         length = len(s)
  9.         for i in range(length,0,-1): #左看
  10.             if isP(s[:i]):
  11.                 p.append(i)
  12.                 break
  13.         for i in range(length): # 右看
  14.             if isP(s[i:]):
  15.                 p.append(i)
  16.                 break
  17.         a = s+s[:p[1]][::-1]
  18.         b = s[p[0]:][::-1]+s
  19.     return a if len(a)<=len(b) else b

  20. # 验证通过
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-26 16:44:28 | 显示全部楼层
  1. def checkPalindrome(string):
  2.     if string == string[::-1]:
  3.         return True
  4.     return False


  5. def makePalindrome(string):
  6.     length = len(string)
  7.     if length==1:
  8.         return string
  9.     else:
  10.         for i in range(1,length-1):
  11.             if checkPalindrome(string[i:]):
  12.                 return string+string[:i][::-1]
  13.             elif checkPalindrome(string[:-i]):
  14.                 return string[length-i:][::-1]+string
  15.             else:
  16.                 continue
  17.         return string+string[:length-1][::-1]
  18. print(makePalindrome('deleveled'))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-26 16:51:25 | 显示全部楼层

可以删掉多余的代码列:
  1. def checkPalindrome(string):
  2.     if string == string[::-1]:
  3.         return True
  4.     return False


  5. def makePalindrome(string):
  6.     length = len(string)
  7.     for i in range(1,length-1):
  8.         if checkPalindrome(string[i:]):
  9.             return string+string[:i][::-1]
  10.         elif checkPalindrome(string[:-i]):
  11.             return string[length-i:][::-1]+string
  12.     return string+string[:length-1][::-1]
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-16 10:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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