2016-04-21 75 views
-3

我不得不更换为字母串下面是每个字母在字母表(即c变得dz成为a)以下每一个字母,大写每个元音(ae,i,o,u),并返回修改的字符串。我试图找到解决方案,而不需要调用任何功能,如sortfind更换给定的字符串以字母在字母表

我有这样的:

def LetterChanges(str) 
    Changed_Letter = "" 
    alphabet = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z] 
    for i in 0..str.length do 
    if str[i] == 
    str[i] = alphabet[i] + 1 
    return str 
end 

,但我迷路了。任何帮助表示赞赏。

+0

jtbandes你是怎么把我的答案放在一个漂亮的灰色方形那样的? –

+0

欢迎来到Stack Overflow。请阅读“[问]”和链接页面,以及“[mcve]”。我们期望获得更多信息:描述您期望的输出结果,以及目前的结果。你遇到了什么问题?你的代码在语法上不正确,所以你应该先处理它。一旦你的代码被Ruby解释器接受为语法上正确的话,那么你将会在一个更好的地方提出一个问题。 –

+2

*为什么*你想避免使用'find'和'sort'?重塑经过充分测试和优化的车轮?虽然这是一个好主意,但当你第一次学习编程时是不实际的。了解算法是非常有用的,但我建议学习使用现有的工具,并且随着时间的推移,您将了解如何构建这些算法,并尝试构建自己的算法。然而,*始终*要注意,需要使用现有的车轮/方法/功能代码,因为它已经过多年的编写和优化,可以解决您不会预料到的问题。 –

回答

-1

你可以试试这个,它会用下面的字母代替一个字母,它也会将元音大写。

def letter_changes(str) 
    alphabets = ('a'..'z').to_a 
    vowels = ["a","e","i","o","u"] 

    for i in 0..(str.length-1) do 
    index = (alphabets.index(str[i]) == (alphabets.size - 1) ? 0 : (alphabets.index(str[i]) + 1)) 
    str[i] = alphabets[index] 
    str[i] = str[i].upcase if vowels.include?(str[i]) 
    end 
    puts str 
end 

## call function 
letter_changes("cadcarz") 

## OUTPUT 
dbEdbsA 
+1

如果您打算提供ruby建议,请正确操作。 1.命名约定未更正。 2.'each' /'each_with_index'应该优先于'for'。 3.不必要的破坏性'upcase!' –

+0

另外,三元运算符可以用简单的'%'运算符替换。 –

2

您被邀请到每个字母“映射”到另一个字母,那么你将要使用的方法Enumerable#map

VOWELS = "aeiou" 
letters = ('a'..'z').to_a 
    #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 
     "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]      
letters.map do |c| 
    <code referencing c> 
end 
    #=> ['b', 'c', 'd', 'E', 'f',..., 'z', 'A] 

现在,让我们填写的代码,使用方法:

  • String#succ,其中,由于一个字符,返回与下一个更高的ASCII值的字符。例如,"b".ord #=> 98,因此"b".sucC#=> "c",因为"c".ord #=> 99。由于"z".sucC#=> 'aa',我们需要将“z”作为特例。 String#succString#next相同。
  • String#include?String#include?,给定字符串,返回truefalse,具体取决于接收器中是否包含include?的参数(字符串)。例如,"cat".include?("at") #=> true; "cat".include?("a") #=> true; "cat".include?("z") #=> false。请注意,VOWELS,因为它以大写字母开头,是一个常数。
  • String#upcase,它将给定字符串中的所有小写字母转换为大写字母(并保留所有其他字符不变)。

letters.map do |c| 
    if c == 'z' 
    'A' 
    else 
    s = c.succ 
    if VOWELS.include?(s) 
     s.upcase 
    else 
     s 
    end 
    end 
end 
    #=> ["b", "c", "d", "E", "f", "g", "h", "I", "j", "k", "l", "m", "n", 
    # "O", "p", "q", "r", "s", "t", "U", "v", "w", "x", "y", "z", "A"] 

此使用case声明和Ruby的ternary operator你可以代替写:

letters.map do |c| 
    case c 
    when 'z' 
    'A' 
    else 
    s = c.succ 
    VOWELS.include?(s) ? s.upcase : s 
    end 
end 

,或者你可以利用的方法String#ordInteger#chr

letters.map do |c| 
    s = ('a'.ord + ((c.ord-'a'.ord+1) % 26)).chr 
    VOWELS.include?(s) ? s.upcase : s 
    end 
end 

如果,例如,c = 'r'

('a'.ord + ((c.ord-'a'.ord+1) % 26).chr 
#=> (97 + ((114-97+1) % 26).chr 
#=> (97 + 18 % 26).chr 
#=> (97 + 18).chr 
#=> 115.chr 
#=> 's' 

但是,如果c = 'z'

('a'.ord + ((c.ord-'a'.ord+1) % 26).chr 
#=> (97 + ((122-97+1) % 26).chr 
#=> (97 + 26 % 26).chr 
#=> (97 + 0).chr 
#=> 97.chr 
#=> 'a' 

另一种方式。 (你可以找出为什么这个工作。)

letters.map do |c| 
    s = c.succ[0] 
    VOWELS.include?(s) ? s.upcase : s 
end 

你可能反而希望创建一个散列。

letter_mapping = {} 
letters.each do |c| 
    s = c.succ[0] 
    letter_mapping[c] = VOWELS.include?(s) ? s.upcase : s 
end 
letter_mapping 
    #=> { "a"=>"b", "b"=>"c", "c"=>"d", "d"=>"E", "e"=>"f", "f"=>"g", "g"=>"h", 
    #  "h"=>"I", "i"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"O", 
    #  "o"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"U", "u"=>"v", 
    #  "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"A"} 

因此,例如,letter_mapping['r'] #=> "s"

随着时间的推移,你会发现,写这个的Ruby的方法是:

letters.each_with_object({}) do |c, letter_mapping| 
    s = c.succ[0] 
    letter_mapping[c] = VOWELS.include?(s) ? s.upcase : s 
end 
    #=> { "a"=>"b", ... "z"=>"A"} 

最后一件事。 Enumerable#map是包含Enumerable模块的每个类的实例方法。其中一类是Array

Array.included_modules 
    #=> [Enumerable, Kernel] 
Array.instance_methods.include?(:map) 
    #=> true 

Array具有使用模块的所有Enumerable的方法,就好像他们在Array定义。这就是为什么当map接收器是一个数组时。

另一类包括EnumerableRange

Range.included_modules 
    #=> [Enumerable, Kernel] 
Range.instance_methods.include?(:map) 
    #=> true 

因此,与其写:

letters = ('a'..'z').to_a 

我们可以(应该)写:

letters = ('a'..'z') 

以及上述所有代码将工作得很好。