说我有两个数组:
var arrayOne = ["Hi", "Hello", "Hey", "Howdy"]
var arrayOne = ["Hi", "Hello", "Hey", "Not Howdy"]
我可以做些什么来比较数组元素的相似程度?在返回75%的函数中因为前三个元素相同但最后一个元素不相同。我在我的项目中使用的数组是字符串,但它们几乎完全匹配,除了一些元素。我需要看看差异有多大。有什么想法吗?
答案 0 :(得分:1)
这两种算法都使用这样的思想:如果你有两个不同长度的数组,你可以拥有的最高相似度是短长度/长长度,这意味着数组长度的差异被计为不匹配。
您可以将所有字词添加到集合中,然后将百分比设置为最长数组的设置/长度的大小。
您可以对两个数组进行排序,然后为每个数组执行一个带有索引变量的循环,并比较两个索引处的值,从而推进具有" lower"的数组的索引。比较中的值,如果它们是等价的,则递增计数器。您的百分比将是最长阵列的计数器/长度。
要考虑的一件事是你想要在奇怪的情况下测量相似性。假设您有两个数组:[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
变量中。
然后迭代第一个数组 - 对于每个元素,序列前进到下一个元素,直到左元素不大于右元素。
完成此操作后,将比较左侧和右侧的相等性,在这种情况下,匹配计数器会递增。
该算法适用于具有重复,不同大小等的数组