Ruby每周一测 - 容易记的电话号码

[quote="Eastsun"]另外,按LZ"通过查找字典把输入的数字变成可能的字母输出"的意思
我的上面代码得到的结果字符串中不会包含数字,也就是某些号码会无解
但我看了下原题,貌似是可以包含数字的,譬如号码"1-800-PICK-UPS "应该可以以"1800-PICK-UPS "形式作为一个解.
我写了个容许数字出现的代码,不过稍微复杂些.[/quote]
贴一个python版本的,惭愧,弄了一晚上 :oops:

#-*- coding: utf-8 -*-
#!/usr/bin/env python
from __future__ import with_statement

button_mapping = {
'A' : 2, 'B' : 2, 'C' : 2,
'D' : 3, 'E' : 3, 'F' : 3,
'G' : 4, 'H' : 4, 'I' : 4,
'J' : 5, 'K' : 5, 'L' : 5,
'M' : 6, 'N' : 6, 'O' : 6,
'P' : 7, 'Q' : 7, 'R' : 7, 'S' : 7,
'T' : 8, 'U' : 8, 'V' : 8,
'W' : 9, 'X' : 9, 'Y' : 9, 'Z' : 9,
}


"""
{ word_signature:word }
"""
signatures = {}

def suffeient(word):
"""
remove empty and un-mapped strings
"""
if not word:
return False
if len(word) >= 2 and word[-2] == "\'":
return False
for c in word:
if not (c.upper() in button_mapping.keys()):
return False
return True

def make_signature(word, sig_dict):
#def action_maker(seq):
# return lambda c: seq.append(c)
sig_tmp = []
#f = action_maker(sig_tmp)
[ sig_tmp.append(str(button_mapping[c])) for c in [c.upper() for c in word] ]
sig_dict[''.join(sig_tmp)] = word


def make_signatures(words):
global signatures
[ make_signature(word, signatures) for word in words if suffeient(word) ]


def build_word_list(number, words_dict, indent=0):
"""
Brief introduction of the algorithm:

Find all of the signatures that are contained in the number in the signature dict
Sort the matched keys in decend order
For each of the matched element:
divide the element into 3 parts: header, matched, reminder
call the build_word_list recursively to find the possible matched word
for the header and reminder parts, respectively
examine the result and return

There might be more than one word having the same signature, it depends the
signature-building algorithm and the signature storage's data structure. In
this solution the words having the duplicated signatures are omitted to
reduce the complexity of the implementation; this simplification should not
(um..., maybe not:-)) affect the correctness of the algorithm.
"""

def compose_result(header, matched, reminder):
ret = "%s-%s-%s" % (header, matched, reminder)
if ret[0] == '-':
return ret[1:]
elif ret[-1] == '-':
return ret[0:-1]
else:
return ret

#print '%sinput:%s' % (indent * '.', number )
if not number:
return True, number
if number in words_dict.keys():
#print '%smatches:%s' % ( indent * '.', words_dict[number] )
return True, number
else:
possible_matches = [num for num in words_dict.keys() if num in number]
possible_matches.sort(lambda a,b:len(a) < len(b) and 1 or -1)
#print '%spossible_matches: %s' % (indent * '.', [ (word, words_dict[word]) for word in possible_matches ])

for matched in possible_matches:
header_num, matched_num, reminder_num = number.partition(matched)
#print "header_num:%s, matched_num:%s, reminder_num:%s" % (header_num, matched_num, reminder_num)
header_matched, header_word = build_word_list(header_num,
words_dict, indent + 1)
reminder_matched, reminder_word = build_word_list(reminder_num,
words_dict, indent + 1)
if header_matched and reminder_matched:
return True, compose_result(header_word, matched, reminder_word)
elif header_matched and not reminder_matched:
return False, compose_result(header_word, matched, reminder_num)
elif not header_matched and reminder_matched:
return False, compose_result(header_num, matched, reminder_word)
elif not header_matched and not reminder_matched:
return False, compose_result(header_num, matched, reminder_num)
else:
pass
return False, number

def output(build_result):
global signatures
ret = ""
grouped_result = build_result[1].split('-')
#print "build result %s, %s:" % build_result
for group in grouped_result:
if signatures.has_key(group):
ret = ret + "-" + signatures[group]
else:
ret = ret + "-" + group
return ret[1:]

def input(number):
return ''.join(str(number).split('-'))


if __name__ == '__main__':
with file('words') as f:
trimed = [ line[0:-1] for line in f ]
make_signatures(trimed)

word_list = build_word_list('118737829', signatures)
print word_list and output(word_list) or "None"

word_list = build_word_list('7425877', signatures)
print word_list and output(word_list) or "None"

word_list = build_word_list('74258777425877', signatures)
print word_list and output(word_list) or "None"

word_list = build_word_list(input('1-800-7425-877'), signatures)
print word_list and output(word_list) or "None"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值