Вот мое решение этой проблемы. С учетом ввода типа
[["A", 13], ["B", 5], ["C", 3], ["D", 1]]
Выход
AABABAACABAACABAACABAD
Ruby-источник программы:
require "pp"
def shuffle (total, num)
ret_arr = Array.new
intervel = total/num.to_f
0.upto(num-1) do |i|
val = i * intervel
ret_arr << val.floor
end
return ret_arr
end
freq_table = [["A", 13], ["B", 5], ["C", 3], ["D", 1]]
pp freq_table
total = 0
freq_table.collect {|i| total += i[1] }
final_array = Array.new(total,0)
print final_array.to_s + "\n\n"
placed = 0
freq_table.each do |i|
placements = shuffle(total - placed, i[1])
placements.each do |j|
free_index = -1
0.upto final_array.size do |k|
free_index += 1 if (final_array[k] == 0 || final_array[k] == i[0])
if j == free_index
final_array[k] = i[0]
break
end
end
end
print "Placing #{i[1]} #{i[0]}s over #{total - placed} positions\n"
pp placements
print final_array.to_s + "\n\n"
placed += i[1]
end
Идея состоит в том, чтобы взять алфавит с наибольшей частотой и сначала распределить его по массиву, размер которого равен общему числу всех элементов. Затем распределите алфавит со второй по величине частотой и распределите по свободному пространству и так далее.
Если у вас есть вопросы, дайте мне знать, и я с удовольствием отвечу.
Радж