質問

のための切れセットA、B、C:はしてもらえると助かりますの決定(グ)があるか否かの要素であると編集:交差点)をBとC?

例:
A:すべての数以上3
B:すべての数少ないよ7
C:すべての数と等しい5

この場合は要素を設定することで、5番る。私はこの仕様として、この数値範囲はほんの一例になります。A、B、Cにも、それは何かに使えます。

役に立ちましたか?

解決

編集: コ仁木!

も置いておくとよいでしょうが B.Count <= C.Count <= A.Count.

D = GetCommonElements(B,C);
if( D.Count>0 && GetCommonElements(D,A).Count >0)
{
    // what you want IS NOT EMPTY
}
else
{
    // what you want IS EMPTY
}

SET GetCommonElements(X,Y)
{
    common = {}
    for x in X:
       if Y.Contains(x):
         common.Add(x);
    return common;
}

効率的な設定の交差点アルゴリズム.


利用できま 分配法の設定

alt text

if(HasCommonElements(A,B) || HasCommonElements(A,C))
{
    // what you want IS NOT EMPTY
}
else
{
    // what you want IS EMPTY
}

bool HasCommonElements(X,Y)
{
    // if at least one common element is found return true(immediately)

    return false
}

他のヒント

私が正しくあなたの質問を理解していた場合は、

、あなたはプログラムで3セット、右の交点を計算したいですか?あなたはBとCの交点に存在するAの要素があるかどうかを確認したい、または他の言葉で、あなたはA、Bとの交点Cが非空であるかどうかを知りたい。

あなたがちょうどそれらを使用することができるはずですので、

多くの言語がセットコンテナと交差アルゴリズムを持っています。 OCamlの中にあなたの例:

module Int = struct
    type t = int
    let compare i j = if i<j then -1 else if i=j then 0 else 1
end;;

module IntSet = Set.Make(Int);;

let a = List.fold_left (fun a b -> IntSet.add b a) IntSet.empty [4;5;6;7;8;9;10];;
let b = List.fold_left (fun a b -> IntSet.add b a) IntSet.empty [0;1;2;3;4;5;6];;
let c = IntSet.add 5 IntSet.empty;;

let aIbIc = IntSet.inter (IntSet.inter b c) a;;
IntSet.is_empty aIbIc;;

BおよびCとの交点としてこの出力偽では、(5を含む)の非空です。もちろん、これは、集合の要素(例では、関数がintモジュールでこのプロパティ定義を比較)比較可能であるという事実に依存している。

あるいはC ++での

#include<iostream>
#include<set>
#include<algorithm>
#include<iterator>

int main()
{
    std::set<int> A, B, C;

    for(int i=10; i>3; --i)
        A.insert(i);
    for(int i=0; i<7; ++i)
        B.insert(i);
    C.insert(5);

    std::set<int> ABC, BC;
    std::set_intersection(B.begin(), B.end(), C.begin(), C.end(), std::inserter(BC, BC.begin()));
    std::set_intersection(BC.begin(), BC.end(), A.begin(), A.end(), std::inserter(ABC, ABC.begin()));

    for(std::set<int>::iterator i = ABC.begin(); i!=ABC.end(); ++i)
    {
        std::cout << *i << " ";
    }
    std::cout << std::endl;

    return 0;
}

疑問がさらに明確にする必要があります。 まず、あなたが範囲で与えられたシンボリックセットで動作するようにしたいですか? そして第二に、それは1時間の問題であるか(はい、質問の安定した部品がどのようなものか?)それは何らかの形で繰り返されることになるだろう?

あなたは範囲で動作するようにしたい場合は、

は、あなたは二分木でこれらを表現し、これらの構造上の労働組合との交差点の操作を定義することができます。ツリーを構築するOを必要とする(N Nログ)し、その結果を見つけることはO(ログn)を必要とすることになるでしょう。 (それはあなたが「それは何もすることができます」で考えたものである場合)にのみ、ツリーセットで完済ないだろうが、効率的な範囲の任意の組み合わせをサポートする柔軟になります。

一方何も手段、要素の任意のセットは、その後、唯一のオプションは、要素を列挙している場合。この場合もOを必要とする(N Nログ)であろうセットB及びCの時間をB +ツリーを構築するが、ここではn個の要素の数であり、第1のケースにおけるnの範囲の数です。後で大きな数桁かもしれないし、もちろん、それは要素の唯一の有限数を表すことができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top