2017-10-20 135 views
-1

这是一个来自应用程序学院准备问题的问题 - 有人可以解释答案。我不明白操作的顺序在这个while循环是如何工作的:Ruby中的操作顺序是什么?

def dasherize_number(num) 
    i = 0 
    dashed = "" 
    num_s = num.to_s 

    while i < num_s.length 
    digit = num_s[i].to_i 
    if i > 0 
     prev_digit = num_s[i-1].to_i 
     if prev_digit%2 == 1 || digit%2 == 1 
     dashed += "-" ## THIS LINE COMES FIRST 

     end 
    end 

    dashed += num_s[i] ## WHY IS THIS ADDED TO "DASHED" FIRST? 

    i += 1 
    end 
    return dashed 
end 

puts(dasherize_number(32467743)) 

结果是3-245-7-7-4-3使所有的奇数有除了两边破折号最终案例。

对于我来说,插入短划线的命令在原始字母后添加到新字符串中并没有任何意义,即使它在代码中位于第一位。

谢谢!

+0

你的意思[运算符优先级(https://开头ruby- doc.org/core-2.2.0/doc/syntax/precedence_rdoc.html)?您应该逐步完成此代码并更好地进行调试,并输出每次迭代的结果。 – tadman

+0

提示:'digit.odd?'可能比模数技巧更易于理解。 – tadman

回答

0

在同时的块的第一次迭代这个条件是不正确的

if i > 0 

但随后该数字被添加到dashed,并从下一个迭代甚至条件为真,这两个东西放在一起可能是混乱你

+0

啊好吧,我陷入了困境。谢谢! –

0

我们来跟踪while代码的前两个迭代。

i = 0 num_s = "32467743"

在while循环。

  • digit = 3i = 0if i > 0 is false,SO dashed = "3"
  • digit = 2i = 1prev_digit = 3if i > 0 is trueif prev_digit%2 == 1 || digit%2 == 1 is true,SO dashed = "3-",那么代码退出if i > 0块,然后虚线正在更新dashed = 3-2

一切正常好吧,为了。

0

以下是一些用于教育目的的替代解决方案。这一次使用odd?flat_map编译的字符部分的数组,然后压缩在一起,并剔除不必要的糠

def dasherize_number(num) 
    num.to_s.chars.map(&:to_i).flat_map do |d| 
    if (d.odd?) 
     [ '-', d, '-' ] 
    else 
     d 
    end 
    end.join('').gsub(/\-\-+/, '-').sub(/\A\-/, '').sub(/\-\z/, '') 
end 

这里有一个通过连续应用几次换人,以获得定期的表达水平工作最终结果:

def dasherize_number(num) 
    { 
    /([13579])/ => '-\1-', 
    /\-\-+/ => '-', 
    /\A\-/ => '', 
    /\-\z/ => '' 
    }.inject(num.to_s) do |n, (rx, sub)| 
    n.gsub(rx,sub) 
    end 
end 
0

添加puts跟踪会发生什么:

def dasherize_number(num) 
    i = 0 
    dashed = "" 
    num_s = num.to_s 
    puts "number=#{num_s}" 

    while i < num_s.length 
    digit = num_s[i].to_i 
    if i > 0 
     prev_digit = num_s[i-1].to_i 
     puts "prev_digit=#{prev_digit} digit=#{digit}" 

     if prev_digit%2 == 1 || digit%2 == 1 
     dashed += "-" ## THIS LINE COMES FIRST 
     puts "dashed in if=#{dashed}" 
     end 
    end 

    dashed += num_s[i] ## WHY IS THIS ADDED TO "DASHED" FIRST? 
    puts "dashed + num=#{dashed}" 

    i += 1 
    end 
    return dashed 
end 

puts(dasherize_number(32467743)) 

执行:

$ ruby -w t.rb 
number=32467743 
dashed + num=3 
prev_digit=3 digit=2 
dashed in if=3- 
dashed + num=3-2 
prev_digit=2 digit=4 
dashed + num=3-24 
prev_digit=4 digit=6 
dashed + num=3-246 
prev_digit=6 digit=7 
dashed in if=3-246- 
dashed + num=3-246-7 
prev_digit=7 digit=7 
dashed in if=3-246-7- 
dashed + num=3-246-7-7 
prev_digit=7 digit=4 
dashed in if=3-246-7-7- 
dashed + num=3-246-7-7-4 
prev_digit=4 digit=3 
dashed in if=3-246-7-7-4- 
dashed + num=3-246-7-7-4-3 
3-246-7-7-4-3 

虚线+ = num_s [I] ##这是为什么加入到 “DASHED” FIRST?

循环以i = 0开始,以便不执行if i > 0

虚线+ =“ - ” ## THIS LINE至上

是,先在线,而不是在执行中,正是因为它是在当时的块取决于if i > 0的,这在第一次迭代期间不执行,允许dashed += num_s[i]将第一个数字添加到空的dashed字符串中。

dashed + num=3 

这只是在第二次迭代为I = 1,使if i > 0为真,并允许dashed += "-"要执行:

dashed in if=3-