从两个不同长度的数组中创建哈希,均匀分布元素

时间:2012-08-10 23:24:14

标签: ruby arrays hash

我有两个不同长度的数组。我想把它们放入哈希中,尽可能均匀地分配元素。

编辑 :对不起,我意识到我没有提供足够的输入。通过“尽可能均匀”,我的意思是:

array1总是包含比array2更多的元素。

array2元素是字符串。最小的单位是单词。

更新目标 对于生成的哈希,我希望基于平均字与数的比率将值分配给键(所有元素array2到array1.join(“”).split(“”))。因此,我将数字分配给尽可能接近平均值的字符串,而不会破坏字符串的完整性。您还可以将结果显示为:

result = {"The older son of a woman" =>[320, 321, 322, 323],...}

我为混淆道歉,我想应用程序的目的让我以一种倒置的方式想到这一点。


我可以将下面的示例代码用于某些情况,但对于某些情况却不行。

array1.clear
array2.clear

array11 = [336, 337, 338, 339, 340, 342, 344, 345, 346, 347, 348]
array22 = ["New research", "suggests that hoarders have unique patterns", "of brain activity", "when faced with making decisions", "about their possessions."] 

array1 =  [320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 331, 332, 333, 334] 
array2 = ["The older son of a woman", "killed at Sunday's mass shooting", "in Wisconsin said she was shot just", "after completing prayers."] 


def hash_from_arrays(array1, array2)
 hash  =  Hash.new{|h,k| h[k] = [] }
  arr_ratio = arr1_to_arr2_ratio(array2, array1)
  start =  0
  last_arr1_to_arr2 = Float(Float(array2.last.split(" ").length)*Float(arr_ratio)).floor
  array1.each_with_index do | element, index|
    arr1_for_arr2_ratio = Float(Float(array2[0].split(" ").length)*Float(arr_ratio)).floor
    hash[element] = array2[0]
    if arr1_for_arr2_ratio + start == index && array2.length > 1
      array2.shift
      start = index
    end
  end
  return hash
end



def arr1_to_arr2_ratio(array1, array2)
  word_count = 0.0
  array1.each{|string| word_count = word_count + string.split(" ").length}
  result = Float(array2.length) / word_count
  return result
end



 hash_from_arrays(array1, array2)
 => {320=>"The older son of a woman", 321=>"The older son of a woman", 322=>"The older son of a woman", 323=>"The older son of a woman", 324=>"The older son of a woman", 325=>"killed at Sunday's mass shooting", 326=>"killed at Sunday's mass shooting", 327=>"killed at Sunday's mass shooting", 328=>"in Wisconsin said she was shot just", 329=>"in Wisconsin said she was shot just", 331=>"in Wisconsin said she was shot just", 332=>"in Wisconsin said she was shot just", 333=>"after completing prayers.", 334=>"after completing prayers."}

编辑 更新了代码,现在它适用于两个阵列..我猜一般情况下工作......如果有人可以提出更好的解决方案,那就是大。

2 个答案:

答案 0 :(得分:1)

我很高兴你有一些解决方案:)

我已经玩了一些你的nevest代码,让我们有:

array1 =  [320, 321, 322, 323, 324]
array2 = ["a a a a a a a a a a a a a a a a", "b"]

irb(main):071:0> pp hash_from_arrays(array1, array2)
{320=>"a a a a a a a a a a a a a a a a",
 321=>"a a a a a a a a a a a a a a a a",
 322=>"a a a a a a a a a a a a a a a a",
 323=>"a a a a a a a a a a a a a a a a",
 324=>"a a a a a a a a a a a a a a a a"}

1)根本没有使用“B”可以吗? 2)array2有17个字,除以array1中的5个键= avg每个键3.4个字。结果是每个键平均16个字,这是3.4的意思。显然,如果“b”被使用了几次,那么平均值将接近3.4。

或许我可能再次理解你的想法中的分布/平均值?

答案 1 :(得分:1)

0)问题描述:

我有两套,我想在它们之间定义一个映射。

首先是一组唯一的字符串,名为SS或"字符串",其项目名为"字符串"。
第一组是有限的,它由NStrings项组成 第一组中的每个字符串可以由任意数量的单词组成,由NumWords(字符串)表示 因此,第一组还提供每个字符串的平均字数的统计特性,由TargetAVG表示。

第二个是一组唯一的数字,名为KK或" keys",其项目名为"一个键"。
第二组是有限的,它由NKeys项目组成 这些数字的确切值是无关紧要的,它们仅用作唯一标识符。

保证第二组的条目多于第一组。

我想在第一组和第二组之间生成映射MM 第二组(键)中的每个项目应恰好分配给第一组(字符串)中的一个项目 此映射必须至少使用第一组(字符串)中的每个项目 第一组(字符串)中的任何项目都可以多次使用 因此,映射还生成来自第一组(字符串)的给定项目的多次使用的统计属性,由NumUses(字符串)表示。

我想生成这样的映射,即字符串中分配给键的字数 生成相同的TargetAVG平均值(或尽可能接近),并带有该字符串的注释 计算到平均值的平均次数。

1)重申:

问题:

  

从固定的一组唯一商品中选择固定数量的不同价值商品,以最适合目标总价值。要选择的项目数大于项目数,这些项目必须多次选择。

额外限制:

  

每个项目必须至少选择一次。

其中:

  

项目= SS
      目标项目数= NKeys
      item value = NumWords(item)* NumUses(item)
      目标总价值= TargetAVG * NKeys(=估计整个映射中的单词总量)

2)让我们尝试降低问题的复杂性:

键数多于字符串+每个字符串必须至少使用一次+每个键必须使用一次 因此,正确生成的映射将包含一个子集,该子集将由映射到不同键的每个字符串组成 因此,键的NString已经部分解决,因为我们知道它们必须与每个字符串一对一匹配,   我们只是不知道订单。例如,我们知道70个密钥中的大约30个必须与30个字符串中的每一个一对一地配对,   但是我们不知道哪个字符串是哪个键。但是,确切的分配顺序从来都不重要,所以我们甚至可以   直接映射它们:第一到第一,第二到第二,......第30到第30 这正是我们为减少问题所做的工作。

因此:

  

- )我们可以随时减少,因为键数多于字符串
   - )并且代表这一点,我们将永远留下一些剩余的钥匙,确切地说(NKeys-NStrings)
   - )保证"每个项目必须至少选择一次的部分解决方案"

完整性检查:
部分解决方案耗尽了键的NStrings,我们留下了(NKeys-NStrings)键。
最终的解决方案必须达到平均等于TargetAVG 我们已经在键的第一个NStrings上使用了所有字符串的NStrings 这意味着我们的部分解决方案保证内部平均为" TargetAVG" 我们留下了一些钥匙 这意味着其余键的映射也应该具有" TargetAVG"的平均值,或尽可能接近。
我们已经满足了要求,我们现在可以随时使用任何字符串,甚至是零。

一切听起来都不错。

3)剩下的问题:

问题类型:

  

选择最适合目标总价值的固定数量的有价值物品。我可以选择任何项目。

其中:

  

项目= SS
      目标项目数=(NKeys-NStrings)
      item value = NumWords(item)* NumUses(item)
      目标总价值= TargetAVG *(NKeys-NStrings)(=剩余映射中估计的总字数)

重要的是,我们希望得到最接近给定值的总和" S"通过使用精确的" X"选秀数量。
这意味着它不是一般的背包包装问题,但它有点像它的子类 Change-making problem。让我们试试它是否适合:

  

我们需要以最少使用不同价值的硬币来交易一定数量的现金     =>
    我们需要在一些不同字数的字符串之间拆分指定数量的单词,并使用X选择。

另外,我们希望有最好的近似值#34;结果是理想是不可能的。

背包问题被归类为NP,并且获得精确或最佳可能是一般的 - 要么是艰难的,要么是非常耗时的。在google上花了一些时间之后,我还没有找到任何可以用精确的N-picks来解决钱问题的现成算法,而且可能这类问题简单地用其他名称知道,我现在不记得了。 。我建议您搜索或询问如何对此类问题进行分类。如果有更精通算法命名的人,你甚至可能会立即找到一个有效的解决方案。

需要考虑的其他事项:您的最佳结果有多严重"需要,而且,真的,它需要多少接近?字符串数量会有多少关键字?字符串的字数会变化多少?任何额外的条件都可能有助于放弃背包并使用一些在这些条件下可能安全的方法。

例如,如果剩余的数量(NKey-NSstrings)很低,只需触发一个完整的指数搜索,检查所有可能性,你一定会得到最好的结果。

另外,如果你不需要一个非常好的结果并且(NKeys-NStrings)很高并且字数相对均匀,那么你可能只需做一个简单的贪婪的分配和几个项目错误分配将使平均值略有偏差(几项除以高NKeys-NStrings =平均值的低分数)。

在其他情况下,或者如果你真的需要最佳匹配,你可能需要进入"动态编程"或"整数线性规划"这可以为类似问题生成近似解决方案。

如果我有任何想法,我会添加它们并留下评论,但实际上我怀疑。出于我的记忆,我已经写了所有的东西,只有当我真的再次盯着算法书时,我才能给你更多的指示,我现在很遗憾没有时间:如果你偶然发现问题的正确分类,请给我留言!