3

Ruby は初めてで、ダイクストラ関数を書こうとしていますが、ハッシュ ソートがまったく機能しないようです

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 に答える