最短の一意に識別する部分文字列


23

文字列のリストが与えられたら、各文字列を、空でない部分文字列の1つで置き換えます。これは、リスト内の他の文字列の部分文字列ではなく、できるだけ短くします。

リストを考えると["hello","hallo","hola"]"hello"ただで置き換える必要があり"e"、この部分文字列がに含まれていないとして、"hallo"そして"hola"、それはできるだけ短くしています。"hallo"いずれかで置き換えることができる"ha"か、"al""hola"のいずれかによって"ho""ol"または"la"

ルール

  • 文字列は空ではなく、同じ大文字と小文字のアルファベットのみを含むと想定できます。
  • このような部分文字列はリスト内の各文字列に存在すると仮定できます。つまり、リスト内の文字列は他の文字列の部分文字列にはなりません。
  • 入力と出力は任意の合理的な形式にすることができます。
  • これはなので、選択した言語でできるだけ少ないバイトを使用するようにしてください。

テストケース

ほとんどの場合、可能な出力は1つだけです。

["ppcg"] -> ["p"] (or ["c"] or ["g"])
["hello","hallo","hola"] -> ["e","ha","ho"]
["abc","bca","bac"] -> ["ab","ca","ba"]
["abc","abd","dbc"] -> ["abc","bd","db"]
["lorem","ipsum","dolor","sit","amet"] -> ["re","p","d","si","a"]
["abc","acb","bac","bca","cab","cba"] -> ["abc","acb","bac","bca","cab","cba"]

関連:最短識別サブストリング -同様のアイデアですが、より複雑なルールと扱いにくい形式です。


""単一の"ppcg"ケースを一意に識別しない(空の文字列)のはなぜですか?
ムースボーイ

2
@MooseBoysはそれののいずれかによって、各文字列を置換、文字列のリストを考えると、空でない部分文字列
氏Xcoder

回答:




4

Pyth、12バイト

mhf!ts}LTQ.:

ここで試してみてください!

使い方

基本的に、リスト内の文字列の1つにのみ出現する(つまり、その文字列に固有の)部分文字列をフィルタリングし、最初の部分文字列を取得します。

mhf!ts}LTQ.:     Full program, Q=eval(stdin_input())
m         .:     Map over Q and obtain all the substrings of each.
  f              And filter-keep those that satisfy (var: T)...
      }LTQ       ... For each string in Q, yield 1 if it contains T, else 0.
   !ts           ... Sum the list, decrement and negate. 
 h               Head. Yields the first valid substring, which is always the shortest.

4

プロローグ(SWI)175 163バイト

S/L/R:-sub_string(S,_,L,_,R).
[H|T]+[I|R]:-string_length(H,L),between(1,L,X),H/X/I,T+R.
R+R.
L-R:-L+R,forall(member(E,L),findall(_,(member(F,R),\+ \+ E/_/F),[_])).

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

ここでのほとんどの事柄はかなり明白なはずですが、次のとおりです。

説明

署名:(+=入力、?=オプション、-=出力、:=式)

  • sub_string(+String, ?Before, ?Length, ?After, ?SubString)
  • string_length(+String, -Length)
  • member(?Elem, ?List)
  • between(+Low, +High, ?Value)
  • findall(+Template, :Goal, -Bag)
  • forall(:Cond, :Action)

\+ \+ただnot not(つまり、一致をブール値に変換します(この場合、両方pのsをppcg別々に一致させないようにします))


それは冗長心blowinglyだという事実を除いて、P:右の仕事のためのツール
ASCIIのみ


4

J30 29 25バイト

1(|:(0{-.&,)"_1]\.)<\\.&>

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

                   <\\.&>        a 3-dimensional array of substrings
1 |:                             transpose each matrix to sort the substrings by length
1              ]\.               all choices where one word is missing
    (0{-.&,)"_1                  for every matrix, flatten, remove substrings
                                  that are present in the corresponding complement,
                                  pick first


3

JavaScript(ES6)、93バイト

a=>a.map(s=>(L=s.length,g=n=>a.every(S=>S==s|!~S.search(u=s.substr(n%L,n/L+1)))?u:g(n+1))(0))

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

どうやって?

入力配列a []内の長さL 各文字列sに対して、n = 0で始まる、再帰関数g()を使用して、sのすべての部分文字列uを生成します。

u = s.substr(n % L, n / L + 1)

たとえば、s = "abc"およびL = 3の場合

 n | n%L | floor(n/L+1) | u
---+-----+--------------+-------
 0 |  0  |       1      | "a"
 1 |  1  |       1      | "b"
 2 |  2  |       1      | "c"
 3 |  0  |       2      | "ab"
 4 |  1  |       2      | "bc"
 5 |  2  |       2      | "c"
 6 |  0  |       3      | "abc"
 7 |  1  |       3      | "bc"
 8 |  2  |       3      | "c"

一部のサブストリングは複数回生成されますが、問題ではありません。重要なのは、長さNのすべてのサブストリングが、長さN + 1のサブストリングの前に生成されていることです。

a []の他の文字列Suが見つからなくなるとすぐにプロセスを停止します。これは、チャレンジルール#2に従って、最悪の場合にu == sのときに発生することが保証されています。

リスト内の文字列は、他の文字列の部分文字列にはなりません

したがって、上記の例では、ステップ78は実際には処理されません。


2

PowerShell、107バイト

($a=$args)|%{$(for($i=0;$i++-lt($g=($s=$_)|% Le*)){0..($g-$i)|%{$s|% s*g $_ $i}|?{!($a-match$_-ne$s)}})[0]}

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

説明

指定された各文字列に対して(および配列全体をに割り当てます$a):

  • 実行for文字列の(ベース1)各サブストリングの長さにわたるループを(文字列自体に割り当て$sとの長さ$g
  • 各長さ($i)について:
    • 0からlength-までのインデックスループを作成し$i、次に各インデックスに対して:
      • 現在の文字列($s)の位置$_(インデックス)および長さの部分文字列を取得します$i
      • その部分文字列をWhere-Object?)に渡し、次の場合にそれを返します。
        • $a現在の文字列を含まない配列()のサブセットは$s、現在の部分文字列に一致しません$_

文字列レベルに戻ると、他の文字列では見つからなかったこの文字列のすべての部分文字列があります。そのため、[0]必要なのは1つだけなので最初の文字列を取得し、次の文字列に進みます。


0

C#(Visual C#Interactive Compiler)、149バイト

a=>a.Select(s=>{var t=s;for(int j=0,k,l=s.Length;j++<l;)for(k=-1;j+k++<l;)if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())j=k=l;return t;})

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

少ないゴルフ...

// a is an input array of strings
a=>
  // iterate over input array   
  a.Select(s=>{
    // t is the result string
    var t=s;
    // j is the substring length
    for(int j=0,k,l=s.Length;j++<l;)
      // k is the start index
      for(k=-1;j+k++<l;)
        // LINQ query to check if substring is valid
        // the tested string is collected in t
        if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())
          // break loops
          j=k=l;
    // return result
    return t;
  })
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.