检查一串是否是一对双胞胎


10

说明

可以通过散布两个字母以形成一个新的字符串来打乱两个字符串,就像可以将两堆纸牌打乱形成一个单独的字符串一样。

例如,可以将字符串HELLOWORLD改组为HWEOLRLLODHEWORLLLDO,或者简单地为HELLOWORLD

这是不是一个洗牌如果没有保存的信件的原始顺序。例如,Din WORLD不能R在改组后出现。EHLLOWRDLO举例来说,这意味着即使其中包含所有原始字母,也不是HELLOand WORLD的改组。

如果可以通过改组两个相同的琴弦来构成双胞胎,则该琴弦是双胞胎的混洗。例如,ABACBDECDE是双胞胎的混洗,因为它可以通过改组ABCDE和形成ABCDEDBEACBCADE不是双胞胎的混洗,因为它不能通过混洗两个相同的琴弦来形成。

计划详情

给定一个输入字符串,0如果不是一对双胞胎,则输出,如果不是一对双胞胎,则输出一个双胞胎字符串。

您可以假设输入字符串的长度(包括4到20个字符),并且完全由大写字母字符组成。它应该能够在合理的时间内运行,例如不到10分钟。

这就是代码高尔夫,所以最短的解决方案是成功的。

示例I / O

> ABACBDECDE
ABCDE

> DBEACBCADE
0

> FFFFFF
FFF

> FFGGG
0

> ABBA
0

> AABB
AB

> AABAAB
AAB

我有一个示例(非高尔夫)实现


示例字符串FGG违反断言that the input string has a length inclusively between four and twenty characters,不要告诉我“永远不要相信用户输入!”,“永远不要相信规范!”。
用户未知,

@userunknown太尴尬了!我对其进行FFGGG了编辑以使其一致。
彼得·奥尔森

1
出于好奇,任何人都可以提出具有次指数级最坏情况时间复杂度的解决方案,或者证明没有解决方案吗?
Ilmari Karonen

Answers:


4

哈斯克尔114

main=getLine>>=putStrLn.f.p;f x=head$[a|(a,b)<-x,a==b]++["0"]
p[]=[([],[])];p(x:y)=do(a,b)<-p y;[(x:a,b),(a,x:b)]

取消高尔夫:

main :: IO ()
main = getLine >>= putStrLn . findMatch . partitions

-- | Find the first partition where the two subsequences are
-- equal. If none are, return "0".
findMatch :: [(String, String)] -> String
findMatch ps = head $ [a | (a,b) <- ps, a == b] ++ ["0"]

-- | Return all possible partitions of the input into two
-- subsequences. Preserves the order of each subsequence.
--
-- Example:
-- partitions "AB" == [("AB",""),("B","A"),("A","B"),("","AB")]
partitions :: [a] -> [([a], [a])]
partitions []     = [([], [])]
partitions (x:xs) = do (a, b) <- partitions xs
                       [(x:a, b), (a, x:b)]

说明:

大多数工作都在该partitions功能中完成。它的工作方式是递归地生成(a, b)列表尾部的所有分区,然后使用列表monad将初始元素x放在每个元素的前面,并收集所有结果。

findMatch通过过滤此列表来工作,以便仅保留子序列相等的分区。然后,它返回第一个分区中的第一个子序列。如果没有剩余,则列表为空,因此"0"将返回末尾附加的内容。

main 只需读取输入,通过这两个功能将其输入并打印即可。


对于那些无法阅读Haskell的人,您能给个解释吗?
威兹德先生2011年

1
@Wizard先生:请参阅编辑。
hammar 2011年

我想我想出了一个相当相似的东西,尽管不算太短,但我却做出了愚蠢的选择,使它彻底失败了。您介意我在Mathematica中实现此算法吗?
威兹德先生2011年

4

R,113个字符

l=length(x<-charToRaw(scan(,'')));max(apply(combn(l,l/2),2,function(i)if(all(x[i]==x[-i]))rawToChar(x[i])else 0))

Ungolfed(而不是使用字符串的函数):

untwin <- function(x) {
  x <- charToRaw(x)
  indMtx <- combn(length(x),length(x)/2)
  res <- apply(indMtx, 2, function(i) {
    if (all(x[i]==x[-i]))
      rawToChar(x[i])
    else
      0
  })
  max(res)
}

untwin("ABACBDECDE") # "ABCDE"
untwin("DBEACBCADE") # 0

该解决方案依赖于将combn索引的所有组合生成为矩阵中的列的函数。apply然后将函数应用于2矩阵中的每一列(维度),并返回字符串或零的向量。max然后找到最大的字符串(胜过0)。

R中的一个很酷的功能是能够选择给定索引向量的向量子集,然后通过否定索引来选择该子集的数:x[i] == x[-i]


进行了一些增量改进并减少了字符数。
汤米

3

Mathematica,87岁

这直接基于hammar的帖子,但希望它足够独特,值得推荐。

<<Combinatorica`

f=Catch[Cases[Characters@#~KSetPartitions~2,{x_,x_}:>Throw[""<>x]];0]&

测试:

f /@ {"ABACBDECDE", "DBEACBCADE", "FFFFFF", "FGG", "ABBA", "AABB", "AABAAB"}
{“ ABCDE”,0,“ FFF”,0、0,“ AB”,“ AAB”}

1

d

string c(string in,string a=[],string b=[]){
    if(in.length==0)return a==b?a;"0";
    auto r=c(in[1..$],a~in[0],b);
    return r=="0"?c(in[1..$],a,b~in[0]):r;
}
void main(){writeln(c(readline));}

使用深度优先递归搜索

我可以使用int i = min(a.length,b.length);if(a[0..i]!=b[0..i])return "0";保护条款更快


在IDEONE上,我尝试使用以下程序启动程序失败void main(){writeln(c("ABCADABCAD"));}-只是D的不同版本,我的错,还有其他吗?什么是“ ABCABCA”?
用户未知,

您需要导入std.stdio; 为IO
棘手的怪胎

1

Ruby,89个字符

s=->a,x,y{a=="\n"?x==y ?x:?0:[s[b=a[1..-1],x+c=a[0],y],s[b,x,y+c]].max}
$><<s[gets,'','']

该代码实现了简单的递归搜索算法。输入必须在STD​​IN上给出。


1

Perl,68个字符

/^((.+)(?{local($x,$,)=($,,$x.$^N)}))+$(?(?{$o=$,eq$x&&$,})|x)/?$o:0

假定输入字符串在$_变量中,输出是表达式的值。输入中的尾随换行符将被忽略。您可以从命令行运行,如下所示:

perl -lne 'print /^((.+)(?{local($x,$,)=($,,$x.$^N)}))+$(?(?{$o=$,eq$x&&$,})|x)/?$o:0'

该代码利用Perl的正则表达式引擎(特别是其嵌入式代码执行功能)进行回溯。基本上,它针对正则表达式的输入字符串匹配^((.+))+$,跟踪所述奇数和偶数子匹配的中$x$,,并在结束拒绝匹配,如果两者不相等的。


这是否有正确的结果AABAAB
彼得·奥尔森

是的,它确实。(实际上,AABAAB此解决方案很简单,因为外部团队只需要匹配两次即可。我花了更长的时间才能AABB正确处理该问题。)
Ilmari Karonen 2011年

1

Python,168个字符

def f(s):
 c=s[0]
 d=i=r=0
 if s==c+c:r=c
 while i+1 and i<=len(s)/2 and not r:
  if i:d=f(s[1:i]+s[i+1:])
  if d:r=c+d
  i=s.find(c,i+1)
 return r
print f(raw_input())
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.