比较具有不同参数数量的多个列表的最佳方法是什么

时间:2016-04-12 12:34:07

标签: tcl

我有4个名单。

list1 = "hello" "hi" "bye" "lol" "rofl" "p1" "p2" "etc"
list2 = "hello" "hi" "bye" "lol" "lmao" "c1" "apple" "mango"
list3 = "hello" "hi" "bye" "lol" "rofl" "p1" "p2" "etc" "mango" "chair" "table"
list4 = "hello" "hi" "bye" "lol" "rofl" "p1" "p2" "etc" "bus" "mango" "apple" "etc"

我想在四个列表中进行比较,并且需要存储在所有列表,3列表,2列表和不匹配参数中匹配的参数。

我可以用来比较多个列表的最佳方式是什么,因为列表中可以有n个参数,n可以在每个列表中有所不同。

目前我在tcl编码。但任何算法都适合我

4 个答案:

答案 0 :(得分:2)

创建字典,其键是单词,值是整数。通过每个列表,如果该单词不存在,请插入值1,如果它存在则增加其值。

要查找单词出现的列表数量,只需将字词作为键询问字典。

答案 1 :(得分:2)

这是一些tcl:

set list1 {hello hi bye lol rofl p1 p2 etc}
set list2 {hello hi bye lol lmao c1 apple mango}
set list3 {hello hi bye lol rofl p1 p2 etc mango chair table}
set list4 {hello hi bye lol rofl p1 p2 etc bus mango apple etc}

foreach var {list1 list2 list3 list4} {
    foreach elem [set $var] {
        lappend in($elem) $var
    }
}
foreach {key lists} [array get in] {
    lappend partition([llength $lists]) $key
}

现在:

% parray in
in(apple) = list2 list4
in(bus)   = list4
in(bye)   = list1 list2 list3 list4
in(c1)    = list2
in(chair) = list3
in(etc)   = list1 list3 list4 list4
in(hello) = list1 list2 list3 list4
in(hi)    = list1 list2 list3 list4
in(lmao)  = list2
in(lol)   = list1 list2 list3 list4
in(mango) = list2 list3 list4
in(p1)    = list1 list3 list4
in(p2)    = list1 list3 list4
in(rofl)  = list1 list3 list4
in(table) = list3

% parray partition
partition(1) = table lmao bus c1 chair
partition(2) = apple
partition(3) = p1 p2 mango rofl
partition(4) = hi bye hello etc lol

答案 2 :(得分:1)

在PHP中,解决方案是:

<?php

// define lists (note the array_flip() calls)
$list = array();
$list[] = array_flip(array("hello", "hi", "bye", "lol", "rofl", "p1", "p2", "etc"));
$list[] = array_flip(array("hello", "hi", "bye", "lol", "lmao", "c1", "apple", "mango"));
$list[] = array_flip(array("hello", "hi", "bye", "lol", "rofl", "p1", "p2", "etc", "mango", "chair", "table"));
$list[] = array_flip(array("hello", "hi", "bye", "lol", "rofl", "p1", "p2", "etc", "bus", "mango", "apple", "etc"));

// create a union of all lists where each member is present only once
$keys = array();
for ($idx = 0; $idx<count($list); $idx++) {
    $keys = $keys+$list[$idx];
}

// iterate over the meta-list
foreach (array_keys($keys) as $key) {
    $found = array();
    for ($idx = 0; $idx<count($list); $idx++) {
        if (isset($list[$idx][$key]))
            $found[] = $idx;
    }
    printf('%s found in lists %s'.PHP_EOL, $key, join(', ', $found));
}


?>

输出:

hello found in lists 0, 1, 2, 3
hi found in lists 0, 1, 2, 3
bye found in lists 0, 1, 2, 3
lol found in lists 0, 1, 2, 3
rofl found in lists 0, 2, 3
p1 found in lists 0, 2, 3
p2 found in lists 0, 2, 3
etc found in lists 0, 2, 3
lmao found in lists 1
c1 found in lists 1
apple found in lists 1, 3
mango found in lists 1, 2, 3
chair found in lists 2
table found in lists 2
bus found in lists 3

<强> Demo 即可。请注意,这是针对PHP的一些优化,以降低代码复杂性。

  • 首先,我们将所有关键字列表放入一个大列表中。我们使用array_flip()将关键字作为键,而不是值。

  • 然后,通过简单地添加数组来创建所有关键字的列表(重复键覆盖,这在我们的情况下是预期的行为)。

  • 然后我们遍历所有关键字的列表。每个关键字都会被计算,并且会显示找到的列表数组。

答案 3 :(得分:1)

假设这个列表数组:

set list(1) {hello hi bye lol rofl p1 p2 etc}
set list(2) {hello hi bye lol lmao c1 apple mango}
set list(3) {hello hi bye lol rofl p1 p2 etc mango chair table}
set list(4) {hello hi bye lol rofl p1 p2 etc bus mango apple etc}

方法1

set res {}
set allWords [lsort -unique [concat $list(1) $list(2) $list(3) $list(4)]]
foreach word $allWords {
    set in {}
    foreach i {1 2 3 4} {
        if {$word in $list($i)} {
            lappend in $i
        }
    }
    lappend res $word $in
}

算法:创建所有唯一单词的列表。对于每个这样的单词,记录它是否出现在数组中的每个列表中。返回一个偶数大小的列表,其中项目0,2,...是一个单词,项目1,3,...是该单词出现的列表编号。

方法2

set res [concat {*}[lmap word $allWords {
    list $word [lmap i {1 2 3 4} {
        if {$word in $list($i)} {
            set i
        } else {
            continue
        }
    }]
}]]

基本相同,但使用Tcl 8.6 lmap命令。

方法3

unset res
foreach i {1 2 3 4} {
    foreach word $list($i) {
        dict lappend res $word $i
    }
}

算法:对于每个列表和单词,lappend使用键res的字典$word中项目的列表编号。 注意:此解决方案的缺点是,如果某个单词在同一个列表中出现多次,则列表编号会多次lappend次。

对结果进行漂亮印刷

lsort -unique是因为方法3的弱点:其他方法没有必要。

proc prettyPrint {word in} {
    set in [lsort -unique $in]
    switch [llength $in] {
        0 {}
        1 {
            puts "$word is in list $in"
        }
        2 {
            puts "$word is in list [join $in { and }]"
        }
        3 {
            puts "$word is in lists [join $in {, }]"
        }
        4 {
            puts "$word is in all lists"
        }
    }
}

foreach {w i} $res {
    prettyPrint $w $i
}

(如果使用方法3,列表将以不同的顺序(单词插入顺序)打印。)

apple is in list 2 and 4
bus is in list 4
bye is in all lists
c1 is in list 2
chair is in list 3
etc is in lists 1, 3, 4
hello is in all lists
hi is in all lists
lmao is in list 2
lol is in all lists
mango is in lists 2, 3, 4
p1 is in lists 1, 3, 4
p2 is in lists 1, 3, 4
rofl is in lists 1, 3, 4
table is in list 3

文档:concatcontinuedictforeachiflappendlist,{{3 }},llengthlmap替代,lmaplsortprocsetswitch