2つの配列に同じ要素が含まれているかどうかを確認する


8

入力2の整数配列を受け取り、両方の配列に存在する要素が存在する場合は真の値を返し、そうでない場合は偽の要素を返すプログラムを記述します。この問題の明らかな解決策は、最初の配列の各要素を反復処理し、2番目の配列の各要素と比較することですが、ここで問題があります。プログラムには、最悪の場合、O( NlogN)、Nはより長い配列の長さ、

テストケース:

 {1,2,3,4,-5},{5,7,6,8} -> false
 {},{0}                 -> false
 {},{}                  -> false
 {1,2},{3,3}            -> false
 {3,2,1},{-4,3,5,6}     -> true
 {2,3},{2,2}            -> true

これはなので、バイト単位の最も短いコードが優先されます。


1
整数はあなたの例のようにバインドされていますか?たとえば、基数ソートまたはビットマップは可能ですか?
Christoph

2
@Pavel私が知る限り、複雑さはセットの実装に大きく依存します。O(n log n)は一般的に実行可能ですが、ネイティブ整数のみの処理に関する明確化は、整数範囲が制限されている一部の言語では線形解が可能であることを意味します(たとえば、2 ^ 64サイズのルックアップテーブルによる)
Sp3000

ちなみに、任意の精度範囲を持つすべてのハッシュベースのソリューションは、衝突の可能性がないこと、または要件の満足を保証する他のいくつかのプロパティを示す必要があると思います。 (現在のルールを使用)
Sp3000

最初の配列(N要素)がソートされている場合は、Nlog(N)です。1配列の「バイナリ検索」を使用した2配列検索の各要素の場合、nlog(N)になるため、合計はNlog(N)+ nlog( N)=(N + n)log(N)は、質問から主張されたNlog(N)に...なので、「ASCIIテーブル」のままですか?
RosLuP 2016年

@RosLuP NLogN + NLogNはまだO(NLogN)
Pavel

回答:


11

実際には、1バイト

オンラインでお試しください!

これは単に組み込みの交差点セットです。結果の値は、2つのセットの共通部分です。共通部分がある場合は空ではないリスト(真の値)、それ以外の場合は空のリスト(誤った値)です。

複雑

Python Wikiによると、セットの交差は最悪の場合の時間の複雑さを持っていますO(N*M)NMは2つのセットの長さです)。ただし、時間の複雑さは、2つのセットにすべて同じハッシュ値を持つ個別のオブジェクト(たとえば、{"some string"} & {hash("some string")})が含まれている場合にのみ悪くなります。この場合、セットの要素は整数のみであり(2つの整数が等しくない限り、同じ値にハッシュされない)、実際の最悪の場合の複雑さはO(min(N, M))(2つのセットのうち小さい方の長さで線形)です。各セットの構造はO(N)(要素数で線形)であるため、全体的な複雑さはO(max(N, M))(複雑さはより大きなセットの構造によって支配されます)。


1
これは、ASCII文字ではありませんUTF-8で3つのバイトを取る
Kh40tiK

7
@ Kh40tiK実際にはエンコードにCP437を使用します。
Mego 2016年

3
これはO(min(N、M))にはできません。両方の配列を読み取るだけでO(max(M、N))時間かかります!どういうわけか私は交差点の設定がそのように迅速に行われることを疑います

3
そうです、私もそれを理解しました。集合の交差は確かにO(min(N、M));です。ただし、配列をセットに変換するには、O(max(N、M))時間かかります。だから我々は両方とも正しかった。

2
Pythonは整数をサポートするためにペナルティが課せられているため、これはかなり奇妙な状況です。Perlはそうではないので、言語の選択によって問題が何であるかを再定義しているため、同じアルゴリズムに対しては複雑さが低くなります。問題を公平にするために、整数と見なされるものについていくつかのルールが必要になる場合があります。(また、ランダム化アルゴリズムが入力で非常に高い確率でO(n log n)で実行される場合にカウントされるかどうかについて。ほとんどの言語には、今日と同様に機能するハッシュテーブルがあります。)

3

TSQL、40 37 36バイト

SQLには配列がありません。代わりにテーブルを使用しています

trueの場合は-1、falseの場合は0を返します

DECLARE @ table(a INT)
DECLARE @2 table(b INT)

INSERT @ values(1),(2),(3),(4),(-5)
INSERT @2 values(5),(6),(7),(8)

SELECT~-sign(min(abs(a-b)))FROM @,@2

やってみて


1
はい!それは
すばらしい

1
このクエリに対して生成された実行プランには、実際に必要なランタイム動作がありますか?
user2357112は

@ user2357112は有効なポイントです。これは適切にスケーリングされません、私はそれを短く保つためにいくつかのコーナーをカットしなければなりませんでした。あなたと私の間で、そして世界の残りの部分でそれを保つことができますか?
t-clausen.dk 16

2

Ruby、37バイト:

exit ($*.map{|x|eval x}.reduce:&)!=[]

定義のように:「入力2の整数配列を受け取り、真の値を返す場合...」の場合、これはプログラムであり、入力で2つの配列を文字列として受け入れ、trueまたはfalseを返します。

関数として-14バイト:

->a,b{a&b!=[]}

複雑:

itnersection(&)演算子のルビのドキュメントには、「効率のためにハッシュとeql?メソッドを使用して要素を比較する」とあります。これはまさに私たちが探しているものだと思います。

経験的に:

$ time ruby a.rb "[*1..1000001]" "[*1000001..2000000]"

real    0m0.375s
user    0m0.340s
sys 0m0.034s

$ time ruby a.rb "[*1..2000001]" "[*2000001..4000000]"

real    0m0.806s
user    0m0.772s
sys 0m0.032s

$ time ruby a.rb "[*1..4000001]" "[*4000001..8000000]"

real    0m1.932s
user    0m1.857s
sys 0m0.073s

$ time ruby a.rb "[*1..8000001]" "[*8000001..16000000]"

real    0m4.464s
user    0m4.336s
sys 0m0.119s

それはそれを確認しているようです。


3
Rubyの組み込みセット交差がO(n log n)で実行されることをサポートするソースはありますか?
マーティンエンダー2016年

1
いいえ、しかしランタイムはそれを確認しているようです。
GB

1
また、他のバージョンは何も出力しないため、有効なプログラムではないため、関数を数える必要があります。
マーティンエンダー2016年

2

Perl、25 + 1 = Dadaと共同で26バイト

print 2<($a{$_}|=$.)for@F

-a(1バイトのペナルティ)で実行します。

以下のプログラムの改善されたバージョン(これは、ソリューションの履歴を確認したり、自分で見つけたソリューションを表示したりするために残されています。さらに説明があります)。この-aオプションは、スペースで区切られた配列を入力として読み取り、それらをに格納します@F%a辞書(としてアクセス$a{$_})を使用して、入力が含まれている入力配列のビットマスクを格納し、1両方の配列に要素が見つかるたびに出力します。 null文字列なので、print何も行いません)。sayPerlでは改行が真実であるため使用できません。パフォーマンスは、プログラムの古いバージョンと漸近的に同じです(ただし、一定の要素に関しては高速です)。

Perl、44 + 1 = 45バイト

$a{"+$_"}|=$.for split}{$_={reverse%a}->{3}

-p(1バイトのペナルティ)で実行します。要素をスペースで区切って、1行に1つの配列を入力します。

これ%aは、値が表示された入力配列のビットマスクを格納するハッシュテーブルを作成することで機能します。1行目と2行目の両方の配列に表示された場合、ビットマスクは値3を格納します。ハッシュし、3に対応するキーがあるかどうかを確認すると、共通の値があるかどうかがわかります。

このアルゴリズムの複雑さは、ハッシュの作成を一定の時間と見なす場合(つまり、Perlのように整数に制限がある場合)はO(n)です。bignum整数(入力を文字列として残すため、このプログラムに入力できる)を使用する場合、アルゴリズム自体の複雑さは、名目上、ハッシュ作成ごとにO(n log n)であり、ハッシュ逆転、つまりO(n log n)になります。ただし、Perlのハッシュアルゴリズムは、悪意を持って選択された入力での潜在的なO(n²)パフォーマンスの影響を受けます。ただし、アルゴリズムはランダム化されているため、その入力が何であるかを判別することはできません(整数で単純にトリガーできない可能性もあります)。そのため、「道徳的に」カウントする複雑さのクラスについては議論の余地があります。幸いなことに、これは問題ではありません

このコードは整数以外の入力に対しては3機能しますが、3 つ以上の配列に対しては機能しません(これはハードコードされているため、3行目の入力は2の累乗ではないため、ビットマスクが正しくないためです)。むしろ面倒なことに、コードは自然に重複要素の1つを返します。これはほとんどすべての場合において"0"真実ですが、Perlでは誤っており、配列では有効な重複要素です。その+ため、出力の前にa を付加して3バイトを無駄にする必要がありました。これは、で重複する配列のエッジケースで真の出力を提供するために見つけた最も安い方法0です。Perl以外の言語(空でない文字列が真実である)から真実と偽の概念を使用することが許可されている場合は、3バイトを節約"+$_"する$_ように変更できます。


perl -apE '$\|=($a{$_}|=$.)==3for@F}{'17少ないバイトでも同じ動作になるはずです;-)
Dada

私は-a旗を知らなかった。それはここで役立つようですよね?私はあなたがさらに2バイトを節約できると思います($\|=}{print 同じ長さであり、後者は-pフラグを回避し、ペナルティのバイトを回避==3でき>2、別のバイトに置き換えることができます)。$1など、すでに変数であるような同情、または変数名のスペース全体をハッシュテーブルとして使用することで、さらに3バイトを節約できます。

-a(および-F)PPCGでは非常に便利です(あちこちでコストがかかるため、anagolfよりも便利です)。の後にスペースが必要なためprint、と同じ長さ-p ... $\=}{ですが、なぜですか。(そうですね、変更できないのは悲しいです$1
Dada

それはより短い文字です。あなたは持っていましたp$\|=}{(7つのキャラクター、pペナルティあり)。私が持っているprint (スペースを含む6つの文字を、)。|ちょうどそこにあなたの計算で逃したと思います。

1
ええと、そうです、私は6まで数えることができないようです。
ダダ

2

Python2 - 41の 30バイト

lambda a,b:bool(set(a)&set(b))

セットの交差:O(min(N、M))ここで、NとMはセットの長さです。

リストからセットへの変換:O(max(N、M))

  • 9バイト節約してくれたJakubeに感謝!set(a).intersection(b)->set(a)&set(b)
  • 2バイトを節約してくれたKadeに感謝!->削除f=

set(a)&set(b)交差メソッドを呼び出す代わりに使用できます。
ジャクベ2016年

あなたはJakubeが言う行う場合は、関数定義を除去するために交差点を比較し{0}、あなたが28バイトにそれを得ることができます:lambda a,b:set(a)&set(b)>{0}
カーデ

1
実際には、{1}&{1}一方で、truthyある{1}&{2}falsyです。あなたはただすることができますlambda a,b:a&b
NoOneIsHere

@SeeOneRhinoそれでは、入力をセットとして受け取る必要がありますよね?リストは交差を実装していません。
Yytsi 2016年

@Kadeが動作しないようです:/ Python2とPython3を試しました。削除f=しても機能します。
Yytsi 2016年

2

公理、439バイト

c:=0;s(x,y)==(free c;if x.1=%i and y.2=%i then(x.2<y.1=>return true;x.2>y.1=>return false;c:=1;return false);if x.2=%i and y.1=%i then(x.1<y.2=>return true;x.1>y.2=>return false;c:=1;return false);if x.1=%i and y.1=%i then(x.2<y.2=>return true;x.2>=y.2=>return false);if x.2=%i and y.2=%i then(x.1<y.1=>return true;x.1>=y.1=>return false);false);r(a,b)==(free c;c:=0;m:=[[%i,j] for j in a];n:=[[i,%i] for i in b];r:=merge(m,n);sort(s,r);c)

これは、リストの最初のリストを[[i、1]、[i、2] ...]として変換します。リストの2番目のリストを[[1、i]、[0、i] ...]として変換します。ここで、i 2のリストをマージするよりも虚数の変数であり、リスト2にリスト1の要素が1つある場合に1つの並べ替えを行うので、最後にO(N log N)になります。ここで、N = lenght list 1 + lenght list 2

ない

-- i get [0,0,1,2,3] and [0,4,6,7]  and build [[%i,0],[%i,0],[%i,1],[%i,2] [%i,3],[0,%i],..[7,%i]]
c:=0
s(x:List Complex INT,y:List Complex INT):Boolean==
  free c  -- [%i,n]<[n,%i]
  if x.1=%i and y.2=%i then
    x.2<y.1=> return true 
    x.2>y.1=> return false
    c:=1
    return false
  if x.2=%i and y.1=%i then
    x.1<y.2=>return true
    x.1>y.2=>return false
    c:=1
    return false
  if x.1=%i and y.1=%i then
    x.2< y.2=>return true
    x.2>=y.2=>return false
  if x.2=%i and y.2=%i then
    x.1< y.1=>return true
    x.1>=y.1=>return false
  false


r(a,b)==
  free c
  c:=0
  m:=[[%i, j]  for j in a]
  n:=[[ i,%i]  for i in b]
  r:=merge(m,n)
  sort(s, r)
  c

結果

(12) -> r([1,2,3,4,-5], [5,7,6,8]), r([],[0]), r([],[]), r([1,2],[3,3]), r([3,2,1],[-4,3,5,6]), r([2,3],[2,2])
   Compiling function r with type (List PositiveInteger,List Integer)
       -> NonNegativeInteger
   Compiled code for r has been cleared.
   Compiled code for s has been cleared.
   Compiling function r with type (List PositiveInteger,List
  PositiveInteger) -> NonNegativeInteger
   Compiled code for r has been cleared.
   Compiling function s with type (List Complex Integer,List Complex
      Integer) -> Boolean
   Compiled code for s has been cleared.

   (12)  [0,0,0,0,1,1]
                                           Type: Tuple NonNegativeInteger

なぜrとsのコードを「クリア」するのか理解できません...


2

PowerShell、88 78 77 23バイト

!!(diff -Inc -Ex $A $B)

私の元からなんと54のバイトオフシェービング用@briantistのおかげで、より短くすることで答え冗長-IncludeEqual-ExcludeDifferent-Not

if(-Not(diff -IncludeEqual -ExcludeDifferent $A $B)){("false")}else{("true")}

Compare-ObjectdiffのエイリアスCompare-Object)のソースが見つからないため、時間の複雑さはわかりません。


1
私はまた、複雑にコメントすることはできませんが、23バイトにすることをを短縮することができます:!!(diff -inc -ex $A $B)
briantist

1
特にPowerShell v5を除外する場合、の-i代わりにを使用して、さらに2バイトバイトを削ることができると思います-incが、5以降では、-Information*共通パラメーターが-iあいまいになります。
ブライアンティスト、2016年

1
私の解決策は完成しました。if声明の中に入れることを意図したものではありませんでした。まったく必要ありません!また、v5にはWindows 10が付属し、v5.1にはServer 2016が付属しています。Windows7 / 2008R2までは、WMF5をダウンロードしてインストールすることもできます。しばらくリリースされました!
ブライアンティスト2016年

1
このあたりで他のPowerShellユーザーに会えてうれしいです。2つのこと-に対するある種の明確な時間の複雑さの評価なしではCompare-Object、これがO(NlogN)であるかどうかは疑問です。第二に、事前定義された変数を介して入力を取ることはノーノーなので、あなたparam($a,$b)は前にまたは類似のものを必要とするでしょう。
AdmBorkBork 2016

1
@wubsセミコロンは必要ないので、それだけですparam($A,$B)!!(diff -Inc -Ex $A $B)-次に、それを.ps1ファイルとして保存し、次のようにコマンドラインから配列を引数として呼び出しますPS C:\Scripts>.\same-element.ps1 @(1,2) @(2,3)
AdmBorkBork


1

R、23バイト

sum(scan()%in%scan())>0

一致する要素が常に1つだけ存在し、それ1が真の値(これはRにある)であると仮定すると、次のように記述できます。

sum(scan()%in%scan())

これは21バイトです。


2
これが私が思っていることをしている場合(Aの各要素について、それがBにあるかどうかを確認してください)、これはO(n * m)の時間の複雑さを持っています。
マーティンエンダー2016年

1

PHP、55 51バイト

<?=count(array_intersect($_GET[a],$_GET[b]))<1?0:1;

使用法:ファイルに保存して、ブラウザーから呼び出します。

intersect.php?a[]=1&a[]=2&a[]=3&b[]=0&b[]=4&b[]=5出力0のためにfalse

intersect.php?a[]=1&a[]=2&a[]=3&b[]=0&b[]=4&b[]=1出力1のためにtrue

複雑さについては、参照を見つけることができませんでしたが、このStackOverflowの投稿によると、スクリプトは問題ありません


PHPの組み込みセット交差がO(n log n)で実行されることをサポートするソースはありますか?
マーティンエンダー2016年

@MartinEnderがチェックしています...
マリオ

1

GolfScript、1バイト

スタック上の配列として入力を直接受け取ることが許可されている場合、この1バイトのGolfScriptソリューションは次の仕様を満たす必要があります。

&

テキストベースのI / Oが必要な場合は、まず入力を評価して、長さを最大2バイトにプッシュする必要があります。

~&

これらのソリューションはどちらも、Rubyの対応する演算子を使用し実装されるGolfScript配列交差演算子を使用ます。配列に一致する要素が含まれていない場合は空の配列(偽)を返し、そうでない場合はすべての一致する要素を含む空でない配列(真実)を返します。

これまでのところ、Ruby配列交差演算子の内部実装または漸近的な複雑さに関するドキュメントは、「効率のためにハッシュとeql?メソッドを使用して要素を比較します」という簡単な説明を超えて見つけることができませんでした。ただし、ハッシュテーブルを使用した妥当な実装はO(n)時間で実行され(ハッシュと比較がO(1)であると想定)、いくつかの簡単なパフォーマンステストでこれが実際に当てはまることが示されています。

実行時間と入力サイズの対数-対数プロット

これらの試験はGolfScriptプログラムを用いて行った~2?.2*,/&整数かかり、kは、2×2つの演算シーケンス生成するk個の 2つの二つの配列に分割し、要素k個の要素とその(明らかに空の)交点を計算します。赤い星は、測定された実行時間を示しTを種々の値に対して(対数スケールで)秒K、機能緑色ラインプロットながらT = C ×2 kのスケーリング定数が、C ≈2 -17.075を最良に選択しました測定データに適合します。

(注:このような対数プロット上で、その任意の形式の多項式関数T = C ×(2 kは)直線を生じるであろう。しかしながら、線の傾きは、指数に依存A、およびデータ上の緑色の線で示されているように、a = 1 と確かに一致します。FWIW このデータセットの数値の最適指数は≈1.00789でした​​。)


0

JavaScript(ES6)、39バイト

(a,b,c=new Set(b))=>a.some(e=>c.has(e))

O(n + m)より悪くなりますが、うまくいけばO(n * m)ほど悪くありません。


0

Rust、103バイト

|a:&[i32],b:&[i32]|!b.iter().collect::<std::collections::HashSet<_>>().is_disjoint(&a.iter().collect())

2つの配列スライス(または完全な配列への参照、スライスへの参照解除を自動的に行う)を取得し、それらをセットにバンドルして、非素性をチェックします。Rust標準ライブラリでセットユニオンがどのように実装されているかはよくわかりませんが、最低でもO(n + m)である必要があります。

コレクションを使用しない場合、私が目にする最も簡単な方法は、両方の配列を並べ替え、それらを注意深くステップオーバーして重複を探すことです。このようなもの

fn overlapping(a: &Vec<i32>, b: &Vec<i32>) -> bool{
    let mut sa = a.clone();
    sa.sort();
    let mut sb = b.clone();
    sb.sort();
    let mut ai = 0;
    let mut bi = 0;
    while ai < a.len() && bi < b.len() {
        if sa[ai] < sb[bi] {
            ai += 1;
        } else if sa[ai] > sb[bi] {
            bi += 1;
        } else{
            return true;
        }
    }
    false
}

しかし、Rust IMOでゴルフを楽しむには突然変異が多すぎる必要があります。


0

Python、11バイト

set.__and__

2つのセットを取り、それらを交差させる組み込み


0

公理、50 221バイト

binSearch(x,v)==(l:=1;h:=#v;repeat(l>h=>break;m:=(l+h)quo 2;x<v.m=>(h:=m-1);x>v.m=>(l:=m+1);return m);0);g(a,b)==(if #a>#b then(v:=a;w:=b)else(v:=b;w:=a);c:=sort(v);for x in w repeat(if binSearch(x,c)~=0 then return 1);0)

ない

--suppose v.1<=v.2<=....<=v.#v
--   binary serch of x in v, return the index i with v.i==x
--   return 0 if that index not exist
--traslated in Axiom from C  book
--Il Linguaggio C, II Edizione 
--Brian W.Kerninghan, Dennis M.Ritchie
binSearch(x,v)==
    l:=1;h:=#v  --1  4
    repeat
       l>h=>break
       m:=(l+h)quo 2   --m=(4+1)/2=5/2=2
                       --output [l,m,h]
       x<v.m=>(h:=m-1) --l x m  h =>  
       x>v.m=>(l:=m+1)
       return m
    0


g(a,b)==   
  if #a>#b then (v:=a;w:=b)
  else          (v:=b;w:=a)
  c:=sort(v)
  --output c
  for x in w repeat(if binSearch(x,c)~=0 then return 1)
  0

g(a、b)は、より大きな配列beetwin aおよびbを取得します。N個の要素があるとします。その配列を並べ替え、他の配列の要素を使用してバイナリ検索を実行します。これはO(Nlog(N))になります。bのaの要素がない場合は0を返し、それ以外の場合は1を返します。

結果

(6) ->  g([1,2,3,4,-5], [5,7,6,8]), g([],[0]), g([],[]), g([1,2],[3,3]), g([3,2,1],[-4,3,5,6]), g([2,3],[2,2])
   Compiling function binSearch with type (PositiveInteger,List Integer
      ) -> NonNegativeInteger

   (6)  [0,0,0,0,1,1]
                                           Type: Tuple NonNegativeInteger

これはO(n * m)で機能しますね。
Pavel

はい、それはO(n * m)ですが、上ではO(n * m)である集合交差も使用します。私のアルゴのみが交差点より先に出る...
RosLuP 2016年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.