3

我是 ruby​​ 新手,我正在尝试编写一个 dijkstra 函数,但我的哈希排序似乎根本不起作用

def distance(start_code, end_code, map)
#initialize hash for distance 
#distance are initialized to -1
dist_hash=Hash.new()
start_hash=Hash.new()
parent_hash=Hash.new()
close_list=Array.new()
find=-1
map.citylist.each do |e|
  dist_hash[e]=[+1.0/0.0]
end

start_hash[start_code]=0
parent_hash[start_code]=start_code

while (start_hash.empty?)==false


   #sort the hash
  start_hash.sort_by {|k,v| v}
  puts 'value'      
  puts start_hash.values()  
   #pop the first item in the hash
  h=start_hash.shift()
  curr_key=h[0]
  curr_val=h[1]
  curr_city=map.findcity(curr_key)
  close_list<<curr_city.code

   #for every one in adjacent list
  curr_city.get_adj_city().each do |e|


     #if it in the close list then igonore
    if close_list.include?(e)==false  
       #if it is not in the start_hash then add to start hash
      if start_hash.has_key?(e)==false
        dist=map.adj_dist(curr_city.code, e)
        dist=dist+curr_val
        start_hash[e]=dist
        parent_hash[e]=curr_city.code
       #if it is in the start_hash check if we have better distance
      else
        dist=map.adj_dist(curr_city.code, e)
        if (dist+curr_val)<start_hash[e]
          parent_hash[e]=curr_city.code
          start_hash[e]=dist
        end
      end
       #end pf checking single adj city
    end
     #end of check if include in close


  end
   #end of check whole list

  if curr_city.code==end_code
    find=0
    break
  end

end
#end of check node
#result
if find==0
  ptr=end_code
  puts ptr
  puts "final list"

  while ptr!=start_code
    ptr=parent_hash[ptr]
    puts ptr
  end
  return 0
else
  return -1
end

结尾

当我尝试调用 d.distance("BUE", "LOS", map)

输出看起来像

value
0
value
1680
4651
value
10053
8047
4651
value
11094
15839
15839
8047
4651
10779
....

这些值在 hash.sort_by 之后立即打印出来,但未排序。我是否正确使用该方法?

4

3 回答 3

9

Ruby 1.9 实际上已经对哈希进行了排序,因此如果您确实想继续将排序结果作为哈希处理,您可以简单地将数组再次转换为哈希:

h = {:a=>1, :c=>3, :b=>5, :d=>2}      # => {:a=>1, :c=>3, :b=>5, :d=>2}
h_sorted = Hash[h.sort_by{|k,v| v}]   # => {:a=>1, :d=>2, :c=>3, :b=>5}
于 2012-10-11T06:53:17.740 回答
7

这些值在 hash.sort_by 之后立即打印出来,但未排序。我是否正确使用该方法?

不。当我不确定某事是如何工作的时,我打开 IRB 并尝试一些事情:

hash = {a:1, b:2, c:4, d: 3}
=> {:a=>1, :b=>2, :c=>4, :d=>3}
hash.sort
=> [[:a, 1], [:b, 2], [:c, 4], [:d, 3]]
hash
=> {:a=>1, :b=>2, :c=>4, :d=>3}
hash.sort_by{|k,v| v }
=> [[:a, 1], [:b, 2], [:d, 3], [:c, 4]]
hash
=> {:a=>1, :b=>2, :c=>4, :d=>3}

sort_by不会改变哈希值,它会返回一个结果。尝试:

哈希 = hash.sort_by{|k,v| v } # <- 不要使用它,它是一个数组,你会误导任何阅读此代码的人。

sorted_tuples = hash.sort_by{|k,v| v }

或类似的东西。

于 2012-10-11T05:46:48.577 回答
1

试试这个

hash = {
  "fred" => 23,
  "joan" => 18,
  "pete" => 54
}

hash.values.sort    # => [18, 23, 54]
hash.sort_by { |name, age| age } # => [["joan", 18], ["fred", 23], ["pete", 54]]
hash.sort_by { |name, age| name } # => [["fred", 23], ["joan", 18], ["pete", 54]]
于 2012-10-11T07:34:37.767 回答