2016-04-12 16 views
1

私は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" 

私は4つのリストを比較し、すべてのリスト、3つのリスト、2つのリスト、および一致するパラメータに一致しないパラメータを保存する必要があります。

nのパラメータがリストにあり、nが各リストで異なる可能性があるため、複数のリストを比較するのに最適な方法は何ですか?

現在、私はtclでコーディングしています。しかし、どのようなアルゴリズムは、PHPで私

+0

私はC++を使用していません。任意のアルゴリズムは私を助けることができる – Nitesh

答えて

1

の罰金で、解決策は次のようになります。

<?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()を使用して、キーワードではなくキーワードとしてキーワードを使用します。

  • 次に、すべてのキーワードのリストは、単に配列を追加することによって作成されます(重複したキーの上書き、この場合、意図した動作です)。

  • 次に、すべてのキーワードのリストを繰り返します。すべてのキーワードがカウントされ、見つかったリストの配列が表示されます。

+0

私は混乱があると思う。私はすべてのリストに表示される要素を望んでいない。私はそれぞれの要素を欲しがっていて、どれくらい多くの要素が要素名で来るのかを知りたい。こんにちは - すべて、bye -all、apple-only list2とlist4、mango-list 2とlist3 – Nitesh

+0

@Nitesh Adaptedのように。 – syck

2

辞書を作成し、そのキーは単語であり、値は整数です。各リストを通過し、単語が存在しない場合は、値1があればその値をインクリメントします。

単語が表示されるリストの数を調べるには、単語をキーとして辞書に質問してください。ここで

+0

'foreach item $ list1 {dict incr itemcount $ item}' –

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 
+0

素晴らしいです。 'apple 'のように表示されたリストを得ることができるかどうかのリストは – Nitesh

+0

です。 'incr count'行の後に' lappend in($ elem)$ var'を追加するとappleは$ apple(apple)になります。 " –

+0

が再構築され、" count "配列はなくなります。 –

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コマンドを使用しています。

方法

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

3アルゴリズム:各リストと単語のための、キー$wordと辞書resの項目にlappendリスト番号。 注:この解決策は、単語が同じリスト内で複数回出現する場合、リスト番号はlappendであり、複数回繰り返されるという欠点があります。結果

lsort -uniqueをPrettyprinting

があるため、方法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,llength,lmap,lmap置換え、lsort,proc,set,switch,unset

関連する問題