数组Swift的相似度百分比

时间:2015-07-07 02:45:14

标签: ios arrays swift

说我有两个数组:

var arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
var arrayOne = ["Hi", "Hello", "Hey", "Not Howdy"]

我可以做些什么来比较数组元素的相似程度?在返回75%的函数中因为前三个元素相同但最后一个元素不相同。我在我的项目中使用的数组是字符串,但它们几乎完全匹配,除了一些元素。我需要看看差异有多大。有什么想法吗?

4 个答案:

答案 0 :(得分:1)

这两种算法都使用这样的思想:如果你有两个不同长度的数组,你可以拥有的最高相似度是短长度/长长度,这意味着数组长度的差异被计为不匹配。

  1. 您可以将所有字词添加到集合中,然后将百分比设置为最长数组的设置/长度的大小。

  2. 您可以对两个数组进行排序,然后为每个数组执行一个带有索引变量的循环,并比较两个索引处的值,从而推进具有" lower"的数组的索引。比较中的值,如果它们是等价的,则递增计数器。您的百​​分比将是最长阵列的计数器/长度。

  3. 要考虑的一件事是你想要在奇怪的情况下测量相似性。假设您有两个数组:[1, 2, 3, 4, 5][1, 1, 1, 1, 1]。我不知道你是否想要说它们完全相似,因为第二个数组中的所有元素都在第一个数组中,或者它们只有20%的相似性,因为一旦第一个中的1数组是"使用",它不能再次使用。

    只是一些想法。

答案 1 :(得分:1)

也许是这样的? (写下我的头顶,所以没有检查它是否真的编译)

var arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
var arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy"]

var matches = 0

for i in 0...arrayOne.count { //assuming the arrays are always the same length
  if arrayOne[i] == arrayTwo[i]{
    matches++
  }
}

var percent = matches / arrayOne.count

答案 2 :(得分:1)

let arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy"]
var matches = 0
for (index, item) in enumerate(arrayOne) {
    if item == arrayTwo[index] {
        matches++
    }
}
Double(matches) / Double(arrayOne.count)   // 0.75

答案 3 :(得分:0)

测量2个数组的相似性的一个好方法是迭代数组的所有元素,并将游标保留在第二个数组上,这样迭代数组的当前元素在任何时候都不大于光标位置。

正如您可能认为的那样,此算法要求元素具有可比性,因此,如果数组类型实现<?= $form->field($model, 'text')->widget(CKEditor::className(), [ 'options' => ['rows' => 6], 'preset' => 'basic', 'clientOptions' => [ 'allowedContent' => ..., ], ]) ?> 接口,则它可以正常工作。

我已经开发了一个执行该计算的通用函数,这里是:

Comparable

让我说实现可能会被优化,但我的目标是展示算法,而不是提供最佳实现。

要做的第一件事是获取2个数组中每个数组的排序版本 - 为简单起见,我已将两个参数都声明为func compare<T: Comparable>(var lhs: [T], var rhs: [T]) -> (matches: Int, total: Int) { lhs.sort { $0 < $1 } // Inline sort rhs.sort { $0 < $1 } // Inline sort var matches = 0 var rightSequence = SequenceOf(rhs).generate() var right = rightSequence.next() for left in lhs { while right != nil && left > right { right = rightSequence.next() } if left == right { ++matches right = rightSequence.next() } } return (matches: matches, total: max(lhs.count, rhs.count)) } ,这允许我编辑它们,将所有更改保留在本地范围内。这就是我使用就地排序的方式。

创建第二个数组上的序列,称为var,并提取第一个元素,将其复制到rightSequence变量中。

然后迭代第一个数组 - 对于每个元素,序列前进到下一个元素,直到左元素不大于右元素。

完成此操作后,将比较左侧和右侧的相等性,在这种情况下,匹配计数器会递增。

该算法适用于具有重复,不同大小等的数组