最短的唯一标识子字符串


23

给定一个字符串列表,请用其非空子字符串之一替换每个字符串,该子字符串不是列表中任何其他字符串的子字符串,并且应尽可能短。

给定list ["hello","hallo","hola"]"hello"应替换为,"e"因为该子字符串未包含在其中"hallo""hola"并且它尽可能短。"hallo"可通过任一取代"ha""al""hola"通过任何"ho""ol""la"

规则

  • 您可以假定字符串将为非空,并且仅包含大小写相同的字母字符。
  • 您可以假定列表中的每个字符串都存在这样的子字符串,即列表中的任何字符串都不是其他任何字符串的子字符串。
  • 输入和输出可以采用任何合理的格式。
  • 这是,因此请尝试使用您选择的语言使用尽可能少的字节。

测试用例

在大多数情况下,仅给出一种可能的输出。

["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"案例?
MooseBoys

2
@MooseBoys 给定一个字符串列表,将每个字符串替换为其非空子字符串之一
Xcoder先生,

Answers:




4

Pyth,12个字节

mhf!ts}LTQ.:

在这里尝试!

怎么运行的

基本上,每个仅过滤出现在列表中的一个字符串中的子字符串(即该字符串唯一),并获取第一个。

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分别))


这项工作的合适的工具:P除了事实,即它是令人blowingly冗长
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))

在线尝试!

怎么样?

对于每一个字符串小号长度的大号在输入数组一个[]和起始与n = 0时,我们使用了递归函数克()生成所有子串ü小号具有:

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 []中的任何其他字符串S中都找不到u,我们便立即停止该过程,根据质询规则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到长度- $i,然后为每个索引:
      • 获取当前字符串($s)在位置$_(索引)处和长度的子字符串$i
      • 将该子字符串传递给Where-Object?),如果满足以下条件,则将其返回:
        • 数组($a)的子集不包含当前字符串$s,不匹配当前子字符串$_

回到字符串级别,我们拥有该字符串在其他字符串中找不到的所有子字符串,因此选择第一个,[0]因为我们只需要其中一个,然后继续下一个字符串。


0

C#(Visual C#交互式编译器),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;
  })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.