锁定老帖子 主题:Ruby每周一测 - 容易记的电话号码
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-21
庄表伟 写道 Eastsun 写道 庄表伟 写道 def build_number_list(words,mapping) number_list={} words.each do |word| number_list[word_to_number(word,mapping)]=word end return number_list.sort end 看了下你的代码(偶从没学过Ruby,说错了勿怪:-)), 按题目中,很可能两个不同的单词对应一个相同的数字(因为每个数字可能对应几个字母) 就是说word_to_number方法对两个word会返回同一个值,那你这样会不会将某些word丢掉了?然后造成结果变少? PS:偶不清楚Ruby中number_list={}是声明了个什么东东,但貌似无论是数组还是Map都会有问题 是会丢掉的。不过这个应该算是题目的问题吧。 如果两个单词的对应数字相同,那么在给定的电话号码,换算的过程中,我该如何选择单词呢? 总不会是根据英语的含义吧。。 题目是要求把所有可能的都求出来 |
|
返回顶楼 | |
发表时间:2008-04-21
先贴一个版本上来,回家再优化。
def word_to_number(word,mapping) number_str="" word.length.times do |i| c=word[i..i] mapping.each_with_index do |abc,index| if abc.include?(c) number_str<<(index+2).to_s end end end number_str.to_i end def build_number_list(words,mapping) number_list={} words.each do |word| unless number_list[word_to_number(word,mapping)] number_list[word_to_number(word,mapping)]=word else number_list[word_to_number(word,mapping)]=number_list[word_to_number(word,mapping)]+","+word end end return number_list.sort end def build_word_list(number, words = %w{USE RUBY} , mapping = %w{ABC DEF GHI JKL MNO PQRS TUV WXYZ}, delimeter = "-") word_list=[number] number_list=build_number_list(words,mapping) number_list.reverse_each do |num_word| num=num_word[0].to_s words=num_word[1].split(",") new_word_list=[] word_list.each do |number_word| words.each do |word| number_word.gsub!(/#{num}/,delimeter+word) number_word=number_word[1..number_word.length] if number_word[0..0]==delimeter new_word_list.insert(-1,number_word) end end word_list=new_word_list end return word_list end p build_word_list("8737829") |
|
返回顶楼 | |
发表时间:2008-04-23
键盘对应字母都是固定的,为了方便没有必要作为参数传进来,而且0、1没有对应的比较麻烦。
初学Ruby,写得很粗糙。 class WordGeneraterB def initialize(n, sp) @n = n @sp = sp @t = ['0', '1'] | ('A'..'Z').to_a @p = [[0,0],[1,1],[2,4],[5,7],[8,10],[11,13],[14,16],[17,20],[21,23],[24,27]] end def g(arr, i) p = @p[i.to_i] cs = @t[p[0]..p[1]] a = [] arr.empty? ? a = cs : cs.each { |c1| arr.each { |c2| a << c2+c1 } } a end def generate raise 'invalid delimeter' unless ('0'..'9').to_a.to_s[@sp].nil? a = [] @n.split('').each { |i| i == @sp ? a.each_index { |x| a[x] += @sp } : a = g(a, i) } a.sort end end puts WordGeneraterB.new('873-7829', '-').generate |
|
返回顶楼 | |
发表时间:2008-04-24
foxgst 写道 键盘对应字母都是固定的,为了方便没有必要作为参数传进来,而且0、1没有对应的比较麻烦。
这里的delimeter参数是为了处理0,1或者其他分词找不到的情况,比如传入18737829,可能的输出就会是: 1-USE-RUBY 和你的解决代码调用有点偏差。 |
|
返回顶楼 | |
发表时间:2008-05-04
发个javascript版本的, 在FireFox3上通过.
function doit(sNumber , dict){ var map = { 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 }; var dict2 = {}; dict.forEach(function(v){ var k = v.split(new RegExp).map(function(i){ return map[i]; }).join(''); dict2[k] ? dict2[k].push(v) : (dict2[k]= [v]); }); var results = []; (function(str, args){ if( !args.length ){ results.push(str) return false; } for(var i =0; i < args.length ; i ++){ if( args[i]=='0' || args[i]=='1' || args[i]=='-'){ arguments.callee(str + args[i], args.slice(i+1) ); continue; } var word = args.slice(0, i+1).join(''); if( dict2[word] ){ for(var j = 0; j < dict2[word].length;j++){ arguments.callee(str + ' ' +dict2[word][j], args.slice(i+1) ); } } } })('', sNumber.split(new RegExp)); alert(results.join("\n")) } doit('8737829', ['USE','RUBY']) |
|
返回顶楼 | |
发表时间:2008-06-04
我没有写代码,先说下我的思路:
以8737829为例 2{a,b,c} 3{d,e,f} 7{p,q,r,s} 8{t,u,v} 9{w,x,y,z} 那么解析这串数字应该可以得到一个符合形式的pattern吧?接下来扫描字典,找出符合pattern的词。 |
|
返回顶楼 | |