1

我有 3 个数组,每个数组都包含一个动态生成的文档列表。(列表根据用户搜索的内容而变化)

$list1['documentname']
$list2['documentname']
$list3['documentname']

该数组是多维的,并包含其他信息,例如描述。

因此,如果我想输出第六个文档的名称和描述,我会写:

echo $list1[5]['documentname'].$newline.$list1[5]['description'];

一个特定的文档可能包含在所有三个列表中,也可能一个列表都不包含。我要做的是使用以下公式按文档总分对文档进行排名:

$document_Score = (1/(60+rank_list1)) + (1/(60+rank_list2)) + (1/(60+rank_list3))

我正在想办法做到这一点,但我无处可去。

如果“文档 a ”在list1中排名第 1 ,在list2中排名第 2 ,在list3中排名第 4 ,我如何应用以下公式并将分数相加。

$document_Score = (1/(60+1)) + (1/(60+2)) + (1/(60+4)) //score for "**document a**"

我知道我需要根据是否$list1['documentname'] is equal to $list2['documentname']等应用代码,但我不知道如何实现这一点。

编辑:

以下代码是我尝试过的。它为list1中的文档提供正确分数,如果 documentname[$i] 值相同,则为list2中的文档评分。

但是这种方法看起来很啰嗦,只能解决一半的问题。似乎我必须在循环内有许多循环来解决这个问题,这不是很有效

for ($i=0;$i<count($list1);$i++)
    {
            $newline="<br />";

        $list1_rank[$i] = $i+1;
        $list2_rank[$i]= $i+1;
        $list3_rank[$i]= $i+1;
        $1ist1_score[$i]= (1/(60+$list1_rank[$i]));


            if ($list1[$i]['documentname']== $list2[$i]['documentname'])
            {
                $list_1_and_2score[$i]=$list1_score[$i]+ (1/(60+$list2_rank[$i]));
            }


            if ($list1[$i]['documentname']!= $list2[$i]['documentname'])
            {
                $list2_score[$i]=(1/(60+$list2_rank[$i]));
            }
            //Outputting the scores calculated:
            echo $newline."List 1 Document Name: ".$list1[$i]['documentname'].$newline."List 2 Document Name: ".$list2[$i]['documentname'].$newline."List 1 Score: $list1_score[$i]".$newline."List 2 Score: $list2_score[$i]".$newline."Combined Score: $list_1_and_2score[$i]".$newline;

    }

另一个问题是 for 循环中的条件$i<count($list1),假设 $list1 是最长的数组,如果 $list3 更长怎么办?我只是说 $i<count($list1) && $i<count($list2) && $i<count($list2)吗?

欢迎任何建议,我将不胜感激。

多谢你们。

4

1 回答 1

2

我们有三个映射,它们按对象在内部的排序方式以及每个对象在哪里是全局唯一的,由它们的“名称”键控来排序。例如,在第一个列表中,MewMew 排名第 1,Spot 排名第 2,Johnny 排名第 3。请注意,MewMew 不在列表 3 中,Ruby 不在列表 1 中。

$list1 = array
(
    array("name" => "MewMew", "description" => "A golden cat."),
    array("name" => "Spot", "description" => "A playful Dalmation."),
    array("name" => "Johnny", "description" => "A big angel fish.")
);

$list2 = array
(
    array("name" => "Spot", "description" => "A playful Dalmation."),
    array("name" => "MewMew", "description" => "A golden cat."),
    array("name" => "Ruby", "description" => "A beautiful parakeet."),
    array("name" => "Johnny", "description" => "A big angel fish.")
);

$list3 = array
(
    array("name" => "Johnny", "description" => "A big angel fish."),
    array("name" => "Spot", "description" => "A playful Dalmation."),
    array("name" => "Ruby", "description" => "A beautiful parakeet.")
);

我建议的方法是创建一个数据结构,它将保存所有三个列表的组合,由它们的全局键“名称”作为键,并为每个条目维护一个运行总分。幸运的是,您为计算聚合选择的算法(SUM ( 1 / (60 + i))非常适合运行计算方法。另请注意,这样做可以让您实际扩展到任意数量的输入列表,而不仅仅是这里给出的三个。

$lists = array($list1, $list2, $list3);
$combinedRank = array();

// We need to process all the input lists.
foreach ($lists as $currentList)
{
    $currentRank = 1; // The first entry is ranked "1".

    // This should perform an in-order traversal of the given list, thus highest
    // ranks will happen first, and the lowest, last:
    foreach ($currentList as $entry)
    {
        if(array_key_exists($entry["name"], $combinedRank))
        {
            // If we've already seen an entry for this name, append the value to the existing combined rank.
            $combinedRank[$entry["name"]] += 1 / (60 + $currentRank);
        }
        else
        {
            // If this the first time we've seen this name, add with initial rank of 1/(60+currentRank).
            $combinedRank[$entry["name"]] = 1 / (60 + $currentRank);
        }

        // Increment the currentRank so that later entries have lower ranks.
        $currentRank++;
    }
}

print_r($combinedRank);

$combinedRank变量包含按名称计算的聚合排名。鉴于当前公式,预期值为:

Spot   = (1 / (60 + 2)) + (1 / (60 + 1)) + (1 / (60 + 2)) ~= 0.0487
Johnny = (1 / (60 + 3)) + (1 / (60 + 4)) + (1 / (60 + 1)) ~= 0.0479
MewMew = (1 / (60 + 1)) + (1 / (60 + 2)) + 0              ~= 0.0325
Ruby   = 0 + (1 / (60 + 3)) + (1 / (60 + 3))              ~= 0.0317

您可以根据需要编写额外的代码来对结果进行排序并提取描述信息。

于 2013-07-06T08:03:52.057 回答