【问题标题】:Ruby Array not sortingRuby数组未排序
【发布时间】:2015-09-14 17:59:44
【问题描述】:

我正在尝试对数组进行排序,但它总是返回相同的原始输入。你知道为什么吗?

puts "Please tell me the array(separated by space, finish by enter twice):"
x = []
input = ' '
while input != ''
  input = gets.chomp
  x.push input
end

puts x.sort

【问题讨论】:

  • 您能否提供一个显示问题的输入和输出示例?
  • 我用了“2423 888 3333 222”,结果还是“2423 888 3333 222”@PhilipHallstrom

标签: arrays ruby sorting


【解决方案1】:

你需要split 输入和concat 到一个奇异数组:

x = [ ]

loop do
  input = gets.chomp

  break if (input.empty?)

  x += input.split
end

puts x.sort

【讨论】:

  • 我认为这是最好的解决方案。 +1
  • 提醒一下:split 相当于split(/\s+/)
  • @theTinMan 好点。这是越少的正则表达式越好。相应更新。
  • 我刚刚添加了一个简单的基准来比较 split 的不同方式。很有启发性。
【解决方案2】:

使用String#split。看看:

 x = '1 3 2 4 55'
 x.split.sort
 #=> ["1", "2", "3", "4", "55"]

如果x 是一个字符串数组,您可以执行以下操作:

x = ['1 3 100', '2 30 4 10']
x.flat_map { |string| string.split }.sort
#=> ["1", "10", "100", "2", "3", "30", "4"] Note it is sorted alphabetically.

如果您想对输入进行数字排序,请考虑:

x = ['1 3 100', '2 30 4 10']
x.flat_map { |string| string.split.map(&:to_i) }.sort
#=> [1, 2, 3, 4, 10, 30, 100]

虽然在现实生活中我更喜欢 @tadman 的解决方案,因为它会立即对输入进行操作,统一输入。

【讨论】:

  • x 是一个数组,而不是一个字符串。不过你走在正确的轨道上。
  • @ray,如果您希望收到一个由空格分隔的单词的字符串,这就是您的问题的解决方案。 +1
  • 更近了,但仍然不存在。您正在对数组进行排序,而不是对单个元素进行排序。 flat_map.flatten 会解决这个问题。
  • 注意:split 等同于split(' ')
【解决方案3】:

思考这个:

x = [] # => []
input = '1 2 3' # => "1 2 3"
x.push input # => ["1 2 3"]
x.sort # => ["1 2 3"]

基本上,您在代码中输入单个字符串,将其推入数组,然后对单个元素数组进行排序。这不会做任何事情,因为您无法对单个元素数组进行排序并获得不同的顺序。 (嗯,你可以期待它会有所不同,但事实并非如此。)

改为:

x = [] # => []
x.push '1' # => ["1"]
x.push '3' # => ["1", "3"]
x.push '2' # => ["1", "3", "2"]

模拟输入三个不同的字符串。排序x 现在返回一个排序数组:

x.sort  # => ["1", "2", "3"]

这里还有一些值得思考的事情:

require 'fruity'

string = ('a'..'z').to_a.join(' ')
string # => "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"

3.times do
  compare do
    split1 { string.split }
    split2 { string.split(' ') }
    split3 { string.split(/\s/) }
    split4 { string.split(/\s+/) }
  end
end

# >> Running each test 1024 times. Test will take about 1 second.
# >> split1 is faster than split2 by 10.000000000000009% ± 10.0%
# >> split2 is faster than split3 by 3x ± 0.1
# >> split3 is similar to split4
# >> Running each test 2048 times. Test will take about 1 second.
# >> split1 is faster than split2 by 10.000000000000009% ± 10.0%
# >> split2 is faster than split3 by 3x ± 0.1
# >> split3 is similar to split4
# >> Running each test 1024 times. Test will take about 1 second.
# >> split1 is faster than split2 by 10.000000000000009% ± 10.0%
# >> split2 is faster than split3 by 3x ± 0.1
# >> split3 is similar to split4

split1split2 的结果大约有 10% 支持 split1,因此,Fruity 有时会报告 10% 的差异,有时则不会。 split3split4 也是如此。

还有:

string = ('a'..'z').to_a.zip(26.times.map{ ' ' * (rand(4) + 1)}).join
string # => "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    "
compare do
  split1 { string.split }
  split2 { string.split(' ') }
  split3 { string.split(/\s/) }
  split4 { string.split(/\s+/) }
end

# >> Running each test 1024 times. Test will take about 1 second.
# >> split1 is similar to split2
# >> split2 is faster than split4 by 3x ± 0.1
# >> split4 is faster than split3 by 2.1x ± 0.1 (results differ: ["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"] vs ["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"])

最后一个结果是不同的,因为split(/\s/) 只寻找单个空白字符,而不是像split(/\s+/) 那样的倍数。我留下这个结果是为了展示 + 对引擎的影响。

【讨论】:

    【解决方案4】:

    如果您在一行中输入所有数字,那么您只需拨打一次gets。见下文。我们读取单行输入,将输入拆分为任意数量的空格并将值转换为其整数形式。然后我们将它们排序显示。

    $ cat foo.rb
    puts "Please tell me the array(separated by space, finish by enter twice):"
    input = gets.chomp
    x = input.split(/\s+/).map(&:to_i)
    puts x.sort
    
    
    $ ruby foo.rb
    Please tell me the array(separated by space, finish by enter twice):
    2423 888 3333 222
    222
    888
    2423
    3333
    

    【讨论】:

    • 这只允许一行输入。
    【解决方案5】:

    您的代码需要在不同的行中输入项目。一个简单的“修复”是调整帮助信息:

    puts "Please tell me the array (one item per line, finish by enter twice)"
    

    并按预期提供物品:

    $ ruby sort.rb
    Please tell me the array (one item per line, finish by enter twice)
    b
    c
    a
    
    
    a
    b
    c
    

    请注意,您的代码会将空行添加到数组中。这可以通过检查input来解决:

    x = []
    input = ' '
    while input != ''
      input = gets.chomp
      x.push input unless input.empty?
    end
    

    使用loopbreak 代替while 可以避免必须检查空input 两次(input != '' / input.empty?)和随机初始值(input = ' '):

    x = []
    loop do
      input = gets.chomp
      break if input.empty?
      x.push input
    end
    

    【讨论】:

      【解决方案6】:

      如果您希望对数字数组进行排序,请更改此行:

      x.push input.to_i
      

      否则输入如下:

      4
      10
      1
      

      将被订购:

      1
      10
      4
      

      如果您需要字符串,那么您的程序应该可以运行,并且应该提供更多详细信息。

      【讨论】:

      • 我期待字符串,但它不会排序:(。例如,“2 aa c b a 9 7 8”,排序后,仍然是“2 aa c b a 9 7 8”@hernanvelasquez
      • 哦,我明白了。看看安德烈的回答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 2018-11-15
      • 2011-02-03
      相关资源
      最近更新 更多