鱼C论坛

 找回密码
 立即注册
查看: 3877|回复: 18

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

[复制链接]
发表于 2017-5-14 18:45:23 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 ooxx7788 于 2017-5-15 10:35 编辑

上一题,我们知道了,摩斯码是由 点("Dot")和划("Dash")组成。
但实际上更准确的说法,应该是摩斯码是由点、划、点和划之间的停顿、每个字符间短的停顿、每个词之间中等的停顿以及句子之间长的停顿组成的。

现在我们来定义一下各个组成部分的时间长度,为了更好的理解这部分,建议你可以自己尝试按出摩斯码的节奏。
1、点("Dot")——1个单位时间长度
2、划("Dash")——3个单位时间长度
3、每个字母内的点和划之间的停顿——1个单位时间长度
4、每个词内字母之间的停顿——3个单位时间长度
5、词与词之间的停顿——7个单位时间长度

然而,实际上无法定义‘单位时间长度’是多长。(个人认为应该是在那个手工发报的年代无法定义)。由于不同的发报人传送的速度可能是不相同的。
业余的发报人需要几秒才能传出一个字母(当你按照我上面说的自己按出摩斯码的节奏是,就会发现自己按的实际很慢),而一个专业的发报人一分钟可以发出60个字母。而机器发报则可以更快。

在这一题中,我们假定收到的是由自动化设备接收的规律性信号。
以下开始是重点了:
当线路接通时(也就是当按下发报键时),记录1。
当线路未接通时(也就是当弹起发报键时),记录0。
当整个信息被完全接收时,你会获得一个只包含了0和1的字符串。

例如:
  1. 信息:HEY JUDE
  2. 摩斯码为:···· · −·−−   ·−−− ··− −·· ·
  3. 字符串为:1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011
复制代码


由此,你可以看出,转换设备非常精确的记录了信息,在这里转换设备采样线路中每个点(DOT)为两个单位时间长度。(由于对于理解转换比较关键,所以我也给出原文,防止我翻译中的不准确。)
As you may see, this transmission is perfectly accurate according to the standard, and the hardware sampled the line exactly two times per "dot".
(译注:只是在此范例中采用的是两倍时长为一个DOT的长度,并不代表所有的测试样本都是两倍时常。其可能是3倍,4倍,也可能是1倍。所以题目第一个函数的要求,就是首先要能判断出频率。)

现在,你的任务是实现两个函数:
1、函数  decodeBits(bits),用于找出信息转换中的频率,准确的将字符串信息解码为由点(.)、划(-)和空格组成的新字符串(也就是上一题中我们传入函数中的参数。)注意:会出现额外的0在开始和结尾,你应当去除掉它们。同时,如果你在辨别个别连续的1是否是点还是划时,假定其为点。
2、函数 decodeMorse(morseCode),这将以上的输出转换为一个人类可读的字符串的函数(其实也就是上一题)。

That's all.
避免我的翻译不准确跟您带来额外困扰,我给出原文的地址:https://www.codewars.com/kata/54b72c16cd7f5154e9000457

我的答案:
游客,如果您要查看本帖隐藏内容请回复






最后找了一张图,这张图说明了,解释了字母的点和划的设置是如何来的。当然,这与本题并无关。

摩斯码.jpg

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2017-5-14 21:03:02 | 显示全部楼层
先写一个,慢慢优化。
  1. def decodeBits(bits):
  2.     lst1 = bits.split('0')
  3.     lst1 = list(set(lst1))
  4.     lst1.sort()
  5.     freq = len(lst1[1])
  6.     str2 = ''
  7.     for i in range(len(bits) // freq):
  8.         str2 += bits[i * freq]
  9.     print(str2)
  10.     str3 = ''
  11.     while str2 != '':
  12.         if str2.startswith('0000000'):
  13.             str3 += '   '
  14.             str2 = str2.lstrip('0000000')
  15.         elif str2.startswith('000'):
  16.             str3 += ' '
  17.             str2 = str2.lstrip('000')
  18.         elif str2.startswith('0'):
  19.             str2 = str2.lstrip('0')
  20.         elif str2.startswith('111'):
  21.             str3 += '-'
  22.             str2 = str2.lstrip('111')
  23.         elif str2.startswith('1'):
  24.             str3 += '.'
  25.             str2 = str2.lstrip('1')
  26.         else:
  27.             print('Error!')
  28.             break
  29.     return str3
复制代码

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

使用道具 举报

 楼主| 发表于 2017-5-14 21:24:45 | 显示全部楼层
冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。


试试看decodeBits('1')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-14 21:33:16 | 显示全部楼层
ooxx7788 发表于 2017-5-14 21:24
试试看decodeBits('1')

修修补补。
  1. def decodeBits(bits):
  2.     lst1 = bits.split('0')
  3.     lst1 = list(set(lst1))
  4.     lst1.sort()
  5.     if lst1[0] == '':
  6.         freq = len(lst1[1])
  7.     else:
  8.         freq = len(lst1[0])
  9.     str2 = ''
  10.     for i in range(len(bits) // freq):
  11.         str2 += bits[i * freq]
  12.     str3 = ''
  13.     while str2 != '':
  14.         if str2.startswith('0000000'):
  15.             str3 += '   '
  16.             str2 = str2.lstrip('0000000')
  17.         elif str2.startswith('000'):
  18.             str3 += ' '
  19.             str2 = str2.lstrip('000')
  20.         elif str2.startswith('0'):
  21.             str2 = str2.lstrip('0')
  22.         elif str2.startswith('111'):
  23.             str3 += '-'
  24.             str2 = str2.lstrip('111')
  25.         elif str2.startswith('1'):
  26.             str3 += '.'
  27.             str2 = str2.lstrip('1')
  28.         else:
  29.             print('Error!')
  30.             break
  31.     return str3
复制代码

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

使用道具 举报

 楼主| 发表于 2017-5-14 21:42:00 | 显示全部楼层
冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。

decodeBits(1110111)

Got 'E', expected 'M'
新三年,旧三年,缝缝补补又3年。
用1来做频率判断,可不一定对哦?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-14 21:44:28 | 显示全部楼层
ooxx7788 发表于 2017-5-14 21:42
decodeBits(1110111)

Got 'E', expected 'M'

我再想想,尽量完善了再发。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-16 00:06:04 | 显示全部楼层
  1. def decodeBits(rawdata):
  2.     rawdata = rawdata.strip('0')
  3.     for i in range(20,0,-1):
  4.         if len(rawdata) % i != 0:
  5.             continue
  6.         else:
  7.             flag = True
  8.             for j in range(len(rawdata)//i):
  9.                 if len(set(list(rawdata[j*i:j*i+i]))) > 1:
  10.                     flag = False
  11.                     break
  12.             if flag:
  13.                 data = rawdata.replace('0'*i, '0').replace('1'*i, '1')
  14.                 return data.replace('0'*7, '   ').replace('0'*3, ' ').replace('1'*3, '-').replace('1', '.').replace('0', '')

  15. def decodeMorse(morse):
  16.     MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
  17.     words = ''
  18.     morselist = morse.strip().split('   ')
  19.     for each in morselist:
  20.         words += ''.join([MORSE_CODE[e] for e in each.split()])
  21.         words += ' '
  22.     return words.strip()

  23. print(decodeMorse(decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-21 10:52:03 | 显示全部楼层
题目都看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-21 11:45:07 | 显示全部楼层

重点都标注出来了,也看不懂哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-22 11:41:21 | 显示全部楼层
  1. MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
  2. def decodeMorse(morseCode):
  3.     c=[]
  4.     ci=morseCode.strip().split('   ')
  5.     for i in ci:
  6.         x=i.strip().split(' ')
  7.         for j in x:
  8.             c.append(MORSE_CODE[j])
  9.         c.append(' ')
  10.     return ''.join(c)


  11. def decodeBits(bits):
  12.     B={'0':'','1':'.'}
  13.     B3={'0':' ','1':'-'}
  14.     if '101' in bits:
  15.         i=1
  16.     elif '1001' in bits:
  17.         i=2
  18.     elif '10001' in bits:
  19.         i=3
  20.     else:
  21.         i=4
  22.     bits=bits[::i]+'0'
  23.     bits='000000000'.join(bits.split('0000000'))
  24.     C=[]
  25.     w=bits[0]
  26.     s=0
  27.     lb=len(bits)
  28.     for j in range(lb):
  29.         if bits[j]==w:
  30.             s+=1
  31.             if s==3:
  32.                 C.append(B3[w])
  33.                 s=0
  34.                 if j<lb-1:
  35.                     w=bits[j+1]            
  36.         else:
  37.             C.append(B[w])
  38.             w=bits[j]
  39.             s=1
  40.     return ''.join(C).strip()
  41.             
  42. x=decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')
  43. print(decodeMorse(x))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 11:46:48 | 显示全部楼层
  1. 10001
  2. Got 'E', expected 'EE'

  3. 111000000000111
  4. Got 'I', expected 'EE'
复制代码


好像还有其他错误。但求值本身也是有问题的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-4 21:32:52 | 显示全部楼层
个人解读一下题目:
实际收到电报内容是1和0,1是点/划,0是停顿
要从中 0、1 出现的频率解码出莫斯密码的内容,再从出莫斯密码中解密出密文

其中,点=1t, 划=3t,字母内点划间停顿=1t, 字母间停顿=3t, 单词间停顿=7t
而t是频率,因人而异,t=1,2,3,4...n
另外,电报首尾的0是无效的,特殊情况不能区分点和划时,默认为点
  1. #这题没有测试,不确定调整方向,某些情况可能会报错
  2. MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5',\
  3.               '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', \
  4.               '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F',\
  5.               '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', \
  6.               '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', \
  7.               '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', \
  8.               '....': 'H', '.----.': "'", '...-': 'V', '--...': '7',\
  9.               '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')',\
  10.               '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/',\
  11.               '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T',\
  12.               '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', \
  13.               '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
  14. s = "1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011"

  15. # 知道对应倍率,只要判断出频率即可,通过0/1中最短的连续次数得出频率,次数相等默认为点
  16. def decodeBits(bits):
  17.     morse = {'1':'.', '111':'-'}   
  18.     b = bits.strip('0')
  19.     if set(b)=={'1'} or set(b)=={'0'}: # 全部0或全部1的情况
  20.         return ""
  21.     zeroes = min([i for i in b.split('1') if i != ""])
  22.     ones = min([i for i in b.split('0') if i != ""])
  23.     hz = min(len(zeroes),len(ones))
  24.     new_b = b[::hz] # 消去频率影响
  25.    
  26.     return "".join([morse[i] if i!="" else " " for i in new_b.split('0')]).replace("  "," ")

  27. def decodeMorse(s):
  28.     return "".join([MORSE_CODE.get(i) if i !="" else " " for i in s.split(" ")]).strip().replace("  "," ")

  29. print(decodeMorse(decodeBits(s)))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-8 15:13:24 | 显示全部楼层
本帖最后由 shigure_takimi 于 2017-12-8 15:14 编辑
  1. MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', \
  2.               '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', \
  3.               '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', \
  4.               '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', \
  5.               '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', \
  6.               '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', \
  7.               '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', \
  8.               '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', \
  9.               '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', \
  10.               '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', \
  11.               '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', \
  12.               '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}

  13. charToMorse = {}
  14. for key in MORSE_CODE:
  15.     charToMorse[MORSE_CODE[key]] = key

  16. def getMorseCode(string):
  17.     string = string.upper().strip().split(' ')
  18.     eachMorse = []
  19.     for word in string:
  20.         if word == 'SOS':
  21.             eachMorse.append(charToMorse[word])
  22.         else:
  23.             wordMorse = []
  24.             for char in word:
  25.                 wordMorse.append(charToMorse[char])
  26.             wordMorse = ' '.join(wordMorse)
  27.             eachMorse.append(wordMorse)
  28.     return '   '.join(eachMorse)

  29. def decodeMorse(morseCode):
  30.     morseCode = morseCode.strip().split('   ')
  31.     allWords = []
  32.     for word in morseCode:
  33.         word = word.strip().split(' ')
  34.         word = ''.join([MORSE_CODE[i] for i in word])
  35.         allWords.append(word)
  36.     return ' '.join(allWords)

  37. def decodeBits(bits):
  38.     bits = bits.strip('0')
  39.     bits = bits.replace('00000000000000','   ')
  40.     bits = bits.replace('000000',' ')
  41.     bits = bits.replace('111111','-')
  42.     bits = bits.replace('11','.')
  43.     bits = bits.replace('00','')
  44.     return bits

  45. a = decodeBits('00110011001100110000001100000011111100110011111100111111000000000000001100111111001111110011111100000011001100111111000000111111001100110000001100')
  46. print(a)
  47. print(decodeMorse(a))

  48. ##  >>>
  49. ##  .... . -.--   .--- ..- -.. .
  50. ##  HEY JUDE
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-12 14:06:47 | 显示全部楼层
  1. MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B',
  2.               '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F',
  3.               '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K',
  4.               '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M',
  5.               '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-',
  6.               '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/',
  7.               '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ',
  8.               '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}

  9. def decodeBits(bits):        
  10.     for t in range(1,len(bits)):       #第一步:用于找出信息转换中的频率t(我的理解是找出最少的连续0的个数)
  11.         if '1'+'0'*t+'1' in bits:
  12.             break
  13.     #第二步:根据频率,把bits转成Morse码   
  14.     return bits.replace('0'*7*t,' '*3).replace('1'*3*t,'-').replace('0'*3*t,' ').replace('1'*t,'.').replace('0'*t,'')   

  15. def decodeMorse(morseCode):    #解析morse码,转成字符      
  16.     res=''
  17.     for ms in morseCode.strip().split(' '):
  18.         if ms=='':
  19.             res+=' '
  20.         else:
  21.             res+=MORSE_CODE[ms]
  22.     return res.replace('  ',' ')  #双空格改为单空格

  23. testbits='1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011'
  24. print('接收到的字符串:',testbits)
  25. print('转换成Morse:',decodeBits(testbits))
  26. print('破译成可识别字符:',decodeMorse(decodeBits(testbits)))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-3 19:02:04 | 显示全部楼层
没读懂。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-28 15:37:56 From FishC Mobile | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-18 19:18:58 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-28 16:01:23 | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-4-12 20:04:33 | 显示全部楼层
完全看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 15:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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