kabhwan
-
Ruby,
pasted
on Aug 7:
|
|
def compare_items_element(item1, item2, elem_idx)
ch_item1 = item1[elem_idx]
ch_item2 = item2[elem_idx]
if !ch_item1 && !ch_item2
nil
elsif !ch_item1
1
elsif !ch_item2
-1
else
ch_item1 <=> ch_item2
end
end
def radix_exchange_recurse(array, start_idx, end_idx, curr_char_idx)
# If start index is equal or higher from end_idx, it doesn't need to sort
return if start_idx >= end_idx
# If all elements' nth char. is nil, sort for current range(set) is complete
all_nil = true
(start_idx..end_idx).each do |idx|
all_nil = nil if array[idx][curr_char_idx]
end
return if all_nil
# sort by current character index
quicksort(array, start_idx, end_idx) do |item1, item2|
compare_items_element(item1, item2, curr_char_idx)
end
p "#{start_idx} ~ #{end_idx} step end... current array is \'#{array.join " "}\'"
# grouping and re-sort
last_char = array[start_idx][curr_char_idx]
char_group_start_idx = start_idx
((start_idx + 1)..end_idx).each do |idx2|
if array[idx2][curr_char_idx] != last_char
radix_exchange_recurse(array, char_group_start_idx, idx2 - 1,
curr_char_idx+1)
last_char = array[idx2][curr_char_idx]
char_group_start_idx = idx2
end
end
# last group
radix_exchange_recurse(array, char_group_start_idx, end_idx,
curr_char_idx+1)
end
def radix_exchange_sort(array)
radix_exchange_recurse(array, 0, array.length - 1, 0)
end
def quicksort(array, begin_idx, end_idx, &compare_block)
return if begin_idx >= end_idx
#p "Quicksorting #{begin_idx} to #{end_idx}..."
pivot_start_idx, pivot_end_idx =
partition(array, begin_idx, end_idx, &compare_block)
#p "Pivot is #{pivot_idx}"
quicksort(array, begin_idx, pivot_start_idx - 1, &compare_block)
quicksort(array, pivot_end_idx + 1, end_idx, &compare_block)
end
# 3-group partition
# less than pivot, equal to pivot, higher than pivot
# http://blogs.microsoft.co.il/blogs/eyal/archive/2009/02/15/interview-question-6-three-way-partition-generic-solution.aspx
def partition(array, begin_idx, end_idx)
pivot_idx = begin_idx
pivot = array[pivot_idx]
first_p = second_p = pivot_idx + 1
third_p = end_idx
while second_p <= third_p
comp_val = yield(array[second_p], array[pivot_idx])
if comp_val > 0
# move to the third partition
array[second_p], array[third_p] = array[third_p], array[second_p]
third_p -= 1
elsif comp_val < 0
# move to the first partition
array[first_p], array[second_p] = array[second_p], array[first_p]
first_p += 1
second_p += 1
else
# leave in the second partition
second_p += 1
end
end
# move pivot to second partiton's first position
array[pivot_idx], array[first_p - 1] =
array[first_p - 1], array[pivot_idx]
return first_p - 1, third_p
end
def make_example_array
%w(add cab fee bad dad bee bed ace)
end
array = make_example_array
p array
radix_exchange_sort(array)
p array
|
Output:
|
|
["add", "cab", "fee", "bad", "dad", "bee", "bed", "ace"]
"0 ~ 7 step end... current array is 'add ace bad bed bee cab dad fee'"
"0 ~ 1 step end... current array is 'ace add bad bed bee cab dad fee'"
"2 ~ 4 step end... current array is 'ace add bad bee bed cab dad fee'"
"3 ~ 4 step end... current array is 'ace add bad bed bee cab dad fee'"
["ace", "add", "bad", "bed", "bee", "cab", "dad", "fee"]
|
|