人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

http://q.hatena.ne.jp/1272277829
の質問を再検討しました。
似ていますが、いくつかの点で簡略化しましたので、
よろしくお願いいたします。

----------------
perlかPHPで解決したいです。

複数(最大20程度)の配列があり、
それぞれ有している数値(それぞれ最大10程度)のうち、
同じ数値を3つ、もしくは4つ持っている配列名を、その数値と共に抜き出す。

という事をしたいです。
どのように表せば良いでしょうか。

例は以下の通りです。

-------------------
例:

配列「Aさん」=1,2,3,4,5
配列「Bさん」=1,2,3,4
配列「Cさん」=1,2,4,100

の場合の結果は以下の通り

1,2,3
Aさん・Bさん

1,2,4
Aさん・Bさん・Cさん

1,3,4
Aさん・Bさん

1,2,3,4
Aさん・Bさん

-------------------



●質問者: love2u2
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:Perl PHP 検討 配列
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● hanako393
●14ポイント

多重ループして地道に調べるしかない


2 ● hnagoya
●40ポイント

問題を誤解していたら申し訳ないのですが、「長さ3もしくは4の部分列を共有する」という解釈でよければ、こんなかんじでいかがでしょうか。

# 例示データ群、各リストは昇順に整列済みであるものとする。
my @samples = (
 ["A", [1, 2, 3, 4, 5]],
 ["B", [1, 2, 3, 4]],
 ["C", [1, 2, 4, 100]],
 );

# リスト @{$a} から長さ $n の部分列のリストを生成するサブルーチン。
sub f {
 my ($a, $n) = @_;
 if (@{$a} == 0) {
 [];
 } elsif ($n == 1) {
 [map { [$_] } @{$a}];
 } else {
 my @a2 = @{$a}[1..@{$a}-1];
 [@{f(\@a2,$n)}, map { [($a->[0], @{$_})] } @{f(\@a2,$n-1)}];
 }
}

# 例示データ群から長さ 3 と 4 の部分列を生成し、その部分列をキーとする
# ハッシュの値を、対応する例示データのリストとする。
my %h;
foreach my $t (@samples) {
 foreach my $v (f($t->[1], 3), f($t->[1], 4)) {
 foreach my $w (@{$v}) {
 my $k = join(",", @{$w});
 $h{$k} = [] unless defined $h{$k};
 push(@{$h{$k}}, $t->[0]);
 }
 }
}

# 結果を表示
foreach my $k (sort { $a cmp $b } keys %h) {
 my $v = $h{$k};
 # 同一のキーを持つ例示データが複数ある場合
 print "$k => @{$v}\n" if @{$v} > 1;
}

3 ● Masa03
●26ポイント

途中までですが、参考までに。

= $arr[$j]){
return false;
}
}
}
return true;
}
function allPattern($max){
if($max>9){ return false; }
for($i=0,$num=''; $i<$max; $i++){
$num .= $i;
}
$pattern[] = sprintf('%0'.$max.'d', $num);

for($l=pow(10, $max); $num<$l; ){
$num++;
if(chkPattern(sprintf('%0'.$max.'d', $num))){
$pattern[] = sprintf('%0'.$max.'d', $num);
}
}
return $pattern;
}

for($i=0; $i<20; $i++){
$a[$i] = createArray();
}
$pattern = array(3 => allPattern(3), 4 => allPattern(4));

header('Content-Type: text/plain; charset=UTF-8');
echo "--- 配列 ---\n";
var_dump($a);
echo "--- 要素の組み合わせ ---\n";
var_dump($pattern);
echo "--- 結果 ---\n";
?>

考え方としては、以下の組み合わせパターンを予め作っておきます。(これは実装済み)

  1. 10の要素の中から3要素を選択する組み合わせ
  2. 10の要素の中から4要素を選択する組み合わせ

で、20の配列に対して比較していくわけですが、初めは $a[0][0] を比較対象にします。

$a[0][0] に対して $a[1]?$a[19] までの間で上の組み合わせパターン全てを試行し、一致するものがないか調べます。

一致したら、$result[] にでも出力しておきます。

全ての組み合わせで比較し終わったら、$a[0][1] で同じ作業を行います。

同じ要領で一つずつ要素をずらしながら比較していき、最終的には $a[18][9] を比較対象に選んだ時点で終わりです。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ