论坛首页 编程语言技术论坛

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

浏览 11355 次
精华帖 (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都会有问题


是会丢掉的。不过这个应该算是题目的问题吧。

如果两个单词的对应数字相同,那么在给定的电话号码,换算的过程中,我该如何选择单词呢?

总不会是根据英语的含义吧。。


题目是要求把所有可能的都求出来
0 请登录后投票
   发表时间: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")
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2008-04-24  
foxgst 写道
键盘对应字母都是固定的,为了方便没有必要作为参数传进来,而且0、1没有对应的比较麻烦。

这里的delimeter参数是为了处理0,1或者其他分词找不到的情况,比如传入18737829,可能的输出就会是:
1-USE-RUBY
和你的解决代码调用有点偏差。
0 请登录后投票
   发表时间: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'])
0 请登录后投票
   发表时间: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的词。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics