在没有排序函数的数组中对字符串进行排序 - Ruby

问题描述 投票:0回答:2

我正在尝试创建一个没有Ruby中的排序功能的排序算法。我基于插入排序的想法。想法是该函数检查每两个单词的第n个值是否相同,如果是,则n增加1,直到一个值大于另一个。在这种情况下,单词可能会被切换。但是,我的功能一直在冻结。有什么想法吗?

words = ["my","favorite","animal", "are", "the", "elephant", "and", "the", "antelope", "and", "the", "favela"]

#Convert all letters into numbers. Output individual words as arrays.
converted_words = words.map(&:chars).map { |letters| letters.map { |letter| letter.to_i 36 } }
puts converted_words.to_s

i = 1
x = 0
while i < converted_words.length
  if converted_words[i][x] == converted_words[i-1][x]
    x = x + 1
  else
    if converted_words[i][x] < converted_words[i-1][x]
      converted_words[i], converted_words[i-1] = converted_words[i-1], converted_words[i]
      i = 0
      x = 0
    else
      i = i + 1
    end
  end
end
puts converted_words.to_s
ruby algorithm sorting insertion-sort
2个回答
2
投票

你的代码没有“冻结”;运行它会引发此异常:

NoMethodError (undefined method '<' for nil:NilClass)

在线:

if converted_words[i][x] < converted_words[i-1][x]

我们立即看到了问题,但原因尚不清楚。 <方法的接收器是converted_words[i][x]。由于错误消息说nil没有方法<,我们推断converted_words[i][x]nil.1这意味着索引超出范围(索引超出范围的例子是[1,2][412] #=> nil[1,2][-3] #=> nil)。如果i超出范围,表达式将减少到nil[x] < ...,这将引发nil没有方法NilClass#\[\]]的例外。这不是我们的异常消息所以我们得出结论x必须超出范围。

要了解为什么会发生这种情况,假设:

words = ["a", "ab"]

然后

converted_words =
  words.map(&:chars).map { |letters| letters.map { |letter| letter.to_i 36 } }
  #=> [[10], [10, 11]] 
i = 1
x = 0
while i < converted_words.length
  #=> while 1 < 2 => while true, so enter the loop
if converted_words[i][x] == converted_words[i-1][x]
  #=> if converted_words[1][0] == converted_words[0][0] => if 10 == 10 => true

所以执行

x = x + 1
  #=> x = 0 + 1 => 1

并尝试重复循环。

while i < converted_words.length
  #=> while 1 < 2 => while true, so repeat the loop
if converted_words[i][x] == converted_words[i-1][x]
  #=> if converted_words[1][1] == converted_words[0][1] => if 11 == nil => false

所以执行(else)。

if converted_words[i][x] < converted_words[i-1][x]
  #=> converted_words[0][1] < converted_words[-1][1] => if nil < 11
  #=> NoMethodError (undefined method '<' for nil:NilClass)

错误消息包含有价值的信息仔细研究它们!

1错误消息“nil没有方法<”在这里相当于,“NilClass没有实例方法<”。


0
投票

我相信我已经解决了这个问题。谢谢你的帮助。

我重新排序了算法:首先检查if converted_words[i][x] < converted_words[i-1][x],然后检查if converted_words[i][x] == converted_words[i-1][x]

我还需要检查是否if converted_words[i][x] != nil && converted_words[i-1][x] != nil,以避免NoMethodError(感谢Cary Swoveland)。最后,我将两种算法结合起来。

我也意识到我不需要将字母转换为数字,因为红宝石知道哪些字母更大。所以相反,我将字符留作字母。

我知道代码效率不高。如果您对如何改进或简化算法有任何建议,我很乐意听到它们。

这是代码:

words = ["my","favorite","animals", "are", "the", "elephant", "and", "the", "antelope", "and", "the", "favela"]
puts words.to_s
#Convert all letters into numbers. Output individual words as arrays.
ordered_words = words.map(&:chars).map { |letters| letters.map { |letter| letter } }

i = 1
x = 0
while i < ordered_words.length
  if ordered_words[i][x] != nil && ordered_words[i-1][x] != nil
    if ordered_words[i][x] < ordered_words[i-1][x]
      ordered_words[i], ordered_words[i-1] = ordered_words[i-1], ordered_words[i]
      i = 1
      x = 0
    else
      if ordered_words[i][x] == ordered_words[i-1][x]
        x = x + 1
      else
        i = i + 1
        x = 0
      end
    end
  else
    if ordered_words[i][x] == nil && ordered_words[i-1][x] == nil
      i = i + 1
      x = 0
    else
      if ordered_words[i][x] == nil
        ordered_words[i], ordered_words[i-1] = ordered_words[i-1], ordered_words[i]
        i = 1
        x = 0
      else
        i = i + 1
        x = 0
      end
    end
  end
end

joined_words = []
ordered_words.each do |word|
  joined_words.push(word.join)
end
puts joined_words.to_s
© www.soinside.com 2019 - 2024. All rights reserved.