最短,字典上最小的生成字符串


16

如果是的无限重复的子字符串,则字符串会x 生成一个字符串。例如产生。yyxabcbcabcab

编写程序以查找将生成输入的最短,字典最小的字符串。在标准输入上会为您提供单行文本。您应该将生成的字符串打印到标准输出。例如:

输入

bcabcabca

输出

abc

最短的代码获胜。您可以假设输入仅包含字符az(如果需要,还可以包含尾随换行符)。


输出应该以任何顺序?说输出可以bac在您的示例中而不是abc
蚂蚁

@GroovyUser:不,输入的不是bacs 重复模式的子字符串。
基思·兰德尔

但是输入可以由的子字符串组成(bca)^n,这意味着bca对给定的例子与一样有效abc
JAB

1
@JAB:bca在字典上不是最小的。
基思·兰德尔

啊,我莫名其妙地错过了那部分。
JAB

Answers:


9

Ruby 1.9,40个字符

gets;a=?a;a.next!until(a*~/$/)[$_];$><<a

假定输入未由换行符终止。同样,要获得更大的结果,它可能太慢了。

$ echo -n "bcabcabca" | ruby genlex.rb 
abc
$ echo -n "barfoobarfoobarfoo" | ruby1.9 genlex.rb 
arfoob

2

Python 88185个字符

import re
s=raw_input()
m=s.index(min(s))
s=s[m:]+s[:m]
i=0
while s.replace(s[:i],''):i+=1
m=min(s[:i])
s=re.findall('%s[\w]*?(?=%s|$)'%(m,m),s[:i])
m=s.index(min(s))
print ''.join(s[m:]+s[:m])

输出:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac

对于某些输入,例如字典“ bacabac”,不会给出字典上最小的字符串
Howard

@霍华德,你是对的。我已经更新了代码,现在已经更长了,但是可以bacabac正确处理字符串。
维达

“ abac”是正确的,请参阅@yogsototh的答案:bacabac abac。
霍华德

2

Haskell,299128个字符

import Data.List
main=interact(\z->minimum$filter(\w->isInfixOf z$concat$replicate(length z)w) $filter((/=)"")$inits=<<tails z)

感谢jloy!现在版本都短得多了,我相信是正确的。


1
因此,好消息是,如果您像在Ventero的Ruby解决方案中那样接受stdin上的输入,则有可能将此解决方案降低到大约91个字符。不幸的是,输入cabcabcabc产生abcabc,所以此解决方案还不存在。我认为您需要进行修改q++q++q才能获得所需的结果。我的快速修复工作使碰撞的东西恢复到145个字符。(扰流器在这里:gist.github.com/1035161

谢谢!我不了解交互,也从来不知道如何初始化<< =尾部来获取所有子字符串。我对您的版本进行了少许修改,以增加一些字符。我删除了排序,并通过filter((/ =)“”“更改了filter(not.null)。再次感谢!
yogsototh 2011年

为什么需要(/=)""条件?它似乎什么也没做。另外,消除lambda也有帮助:您可以使用.operator 完全消除它们,并更改main函数main=interact s以保存几个字符。
Rotsor 2011年

我认为“ bca”的答案是错误的。它应该是“ abc”,但现在是“ bca”。
Rotsor 2011年

一种可能的解决方案是使用permutations代替tails
Rotsor 2011年

2

Python,121137129 字符

s=raw_input()
n=len(s)
l=[(s+s)[i/n:i/n+i%n+1]for i in range(n*n)]
print min(filter(lambda x:(x*len(s)).find(s)+1,sorted(l)),key=len)

编辑:修复了JiminP发现的错误


哇,太好了!不幸的是,它打印aabab为字符串ababa... :(
JiminP 2011年

好吧,已修复...它变得越来越长了:(
JulesOlléon2011年

2

Ruby 1.9、36

$><<(?a..gets).find{|s|(s*~/$/)[$_]}

使用与Ventero解决方案相同的方法。


2

蟒蛇, 161159166140141134 132个字符

y=raw_input();i=n=l=len(y)
while i:
 if (y[:i]*l)[:l]==y:n=i
 i-=1
x=y[:n];y=x*2
while i<n:
 x=min(x,y[i:i+n])
 i+=1
print x

编辑:阅读JulesOlléon的评论后,仔细研究了代码。删除了bcdabcdab导致的“错误” abbc

EDIT2:修复了JulesOlléon发现的错误(abaa导致aaa)。

我对Python不太了解,因此这段代码可能是“不熟悉的”。

我喜欢这个规则:

您可以假设输入仅包含字符az ...

输入和输出

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab

1
褐狐,快!狗,懒!
JiminP 2011年

好的解决方案,很短,可能是这里最好的复杂性!您可以打些高尔夫-例如,您不需要“ int”来比较琴弦;并将“ while i> 0”替换为“ while i”,将“ y = y + y”替换为“ y * = 2”。
JulesOlléon2011年

其实有一个问题:对于abaa,它会打印aaa ...
JulesOlléon2011年

@Jules感谢您的评论!我没想到那个...
JiminP 2011年

您可以i-=1代替i=i-1。对于增量也是如此。
Lowjacker 2011年

1

Mathematica 124字节

x = StringLength@(y = "");
For[i = 1, ! (s = y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];
First@Sort@StringPartition[s <> s, i, 1]

空格和换行符(在行尾存在分号时)在Mathematica中没有任何意义,此处将其包括在内以提高可读性。

输入在第一行的引号之间。如果重铸为函数,则需要像这样输入字符串:

f=(x=StringLength@(y=#);For[i=1,!(s=y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];First@Sort@StringPartition[s<>s,i,1])&

f@"bca"

(* "abc" *)

f@"abaa"

(* "aab" *)

那么是128个字节

For环取第一i输入的字符,并将其重复至少直到输入的长度,然后检查是否输入是结果的子串。找到了字符串周期的长度后,该StringPartition命令会连接该周期的两个副本,并从中获取该长度的所有子字符串(基本上获得所有循环排列),然后First@Sort按字典顺序查找其中的第一个。


0

javascript 96个字符。

var temp = {},len = str.length;
for(i in str) 
temp[str[i]] = true;
Object.keys(temp).join(""); 

工作朋克


1
欢迎来到社区!我无法测试您的代码,您能否提供从GET / POST读取的代码,并使用alert或console.log编写代码,还是提供将输入作为参数并返回输出的函数?
亚伦

@AaronGOUZIT添加了pluckr
ngLover

谢谢,有帮助。但是,您发布的代码仍然不能单独使用,从而欺骗了字节数。更重要的是,恐怕您的代码不遵守规范:我相信您会返回一组使用的唯一字母,而不是“生成字符串”,我们应该能够(整体上)使用可选的截断来重复这些字母获取输入。期待看到您更新的代码!
亚伦
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.