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さん

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

回答の条件
  • 1人3回まで
  • 13歳以上
  • 登録:2010/04/27 21:41:14
  • 終了:2010/05/04 21:45:02

回答(3件)

id:hanako393 No.1

hanako393回答回数1142ベストアンサー獲得回数872010/04/28 00:33:05

ポイント14pt

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

id:hnagoya No.2

hnagoya回答回数26ベストアンサー獲得回数32010/04/28 03:31:10

ポイント40pt

問題を誤解していたら申し訳ないのですが、「長さ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;
}
id:Masa03 No.3

Masa03回答回数3ベストアンサー獲得回数02010/04/28 14:38:51

ポイント26pt

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

= $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] を比較対象に選んだ時点で終わりです。

コメントはまだありません

この質問への反応(ブックマークコメント)

トラックバック

  • データの重複を調べる ちょいと http://q.hatena.ne.jp/1272372071 用に書いたスクリプトのメモ まずはデーター定義部。やけくそに長い。このテストデータは自動生成している。 あまりに長いので
  • 積集合の抽出に挑む 1 まずは用語と共に、何をしようとしているのかを述べる。 集合とはモノの集まりとする。例えば集合A={1,2,3},集合B={2,3,5}など。 次に積集合とは、対象となるどの集合
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません