寻找“亚回文”。


24

查找字符串的所有唯一 “子回文” 的最短代码,即:任何长度大于1的子字符串都是回文。

例如1

input: "12131331"
output: "33", "121", "131", "313", "1331"

例如2

input: "3333"
output: "33", "333", "3333"

1
字符串可以是它自己的子回文吗?由于字符串是它自己的子字符串。
JPvdMerwe,2011年

@JPvdMerwe:是的,当然了。
Eelvex

实际上更重要的是:333be 的输出必须是什么?天真地,您最终要打印33两次
JPvdMerwe 2011年

@JPvdMerwe:“ 333”->“ 33”,“ 333”。我将相应地编辑问题。谢谢。
Eelvex

如何指定输出?正如您在此处演示的那样,用引号引起来的逗号分隔每个子回文?每行一小分?
乔伊

Answers:


11

J,24 31 40

~.(#~(1<#*]-:|.)&>),<\\.

样品使用:

   ~.(#~(1<#*]-:|.)&>),<\\. '12131331'
┌───┬───┬───┬────┬──┐
│121│131│313│1331│33│
└───┴───┴───┴────┴──┘
   ~.(#~(1<#*]-:|.)&>),<\\. '3333'
┌──┬───┬────┐
│33│333│3333│
└──┴───┴────┘

接受,GolfScript!


承认,你只是从/dev/random这里放了一个垃圾场来骗我们;-)
Joey

@Joey自己尝试; p(TBH,我不认为一开始它也可以工作)
JB

我相当确定这是实际的代码。我花了一个周末试图把头缠在J上,但失败了。尽管如此,我仍能识别代码。我只是不明白它的作用;-)
Joey

2
不能缩短为~.(#~(1<#*]-:|.)&>),<\\.24个字符吗?
ephemient 2012年

@ephemient确实如此。(好像我陷入了“答案一定是函数”的思维定式中,在这里并不适用。)编辑,谢谢!
JB 2012年

7

Python 124

r=raw_input()
l=range(len(r))
print', '.join(set('"'+r[i:j+1]+'"'for i in l for j in l if i<j and r[i:j+1]==r[i:j+1][::-1]))

5

Haskell 98、88 91 96

import List
main=interact$show.filter(\x->length x>1&&x==reverse x).nub.(tails=<<).inits

3

蟒- 138 136

此代码不重复子回文。

r=raw_input()
i,l=0,len(r)
j=l
a=[]
while i<l-1:
 t=r[i:j];j-=1
 if t==t[::-1]:a+=['"'+t+'"']
 if j<i+2:i+=1;j=l
print", ".join(set(a))

1
更改'"'+t+'"'t节省一些空间,尽管它使用单引号。
Thomas O

3

Ruby- 126102 97个字符

s=gets
*m=*0..s.size
puts m.product(m).map{|h,j|(c=s[h,j+1]).size>1&&c==c.reverse ? c:0}.uniq-[0]

3

Golfscript,48个字符

下回文

{,}{(;}/{{,}{);}/}%{+}*{.,1>\.-1%=*},.&{`}%", "*

用法:

echo "12131331" | ruby golfscript.rb subpalindrome.gs

第一个操作{,}{(;}/将字符串转换为尾随子字符串列表。然后将类似的前导子字符串转换映射到结果上。然后用压扁{+}*,使用谓词过滤回文,用.,1>\.-1%=*捕获唯一值.&,然后漂亮打印。

将尾随子字符串转换提取为一个块,然后在反转每个尾随子字符串之后将其重新用作前导子字符串的替代方法,这会更整洁,但是我无法找出一种简洁的方法。


2

哈斯克尔- 170,153

import Data.List
import Data.Set
p a=fromList$[show x|x<-subsequences a,x==reverse x,length x>1]
main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)

替换main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)main=getLine>>=putStrLn.intercalate", ".toList.p。我也可以p用它的主体代替呼叫。
Yasir Arsanukaev'2

子串/ = subsequences!您的程序报告的亚回文孢子比示例1的参考输出多。(例如“ 1111”)
JB

2

J,48

f=:,@:".
h=:\\.
~.(#~10&<)((]h-:"0&f|.h)#[:f]h)

例如

~.(#~10&<)((]h-:"0&f|.h)#[:f]h) '12131331'
121 131 313 1331 33

2

Prolog,92岁

f(S,P):-append([_,X,_],S),X=[_,_|_],reverse(X,X),atom_codes(P,X).
p(S,R):-setof(P,f(S,P),R).

样品使用:

?- p("12131331",R).
R = ['121', '131', '1331', '313', '33'].

?- p("3333",R).
R = ['33', '333', '3333'].

2

Windows PowerShell中,104 109 111

0..($l=($s="$input").length-1)|%{($a=$_)..$l|%{-join$s[$a..$_]}}|sort -u|?{$_[1]-and$_-eq-join$_[$l..0]}

这期望在stdin上输入,并将在stdout上每行抛出所有发现的回文数:

PS Home:\SVN\Joey\Public\SO\CG183> '12131331'| .\subp.ps1
33
121
131
313
1331

(从cmd它开始运行时echo 12131331|powershell -file subp.ps1$input取决于脚本的调用方式,它的含义略有不同,但是可以标准输入,而不必是交互式的。)

2011-01-30 13:57(111)–第一次尝试。

2011-01-30 13:59(109)–内联变量声明。

2011-06-02 13:18(104)–通过加入char数组(而不是调用)来重做子字符串查找,.Substring()并内联了更多内容。


2

问78

{a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}

用法

q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"12131331"
"121"
"131"
"313"
"1331"
"33"
q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"3333"
"33"
"333"
"3333"

2

视网膜34 27字节

&@!`(.)+.?(?<-1>\1)+(?(1)^)

在线尝试!

测试套件需要一个 M因为它之后是另一个阶段,在测试用例之间插入空行。

说明

&@!`(.)+.?(?<-1>\1)+(?(1)^)

打印(!)正则表达式的所有唯一(@),重叠(&)匹配项(.)+.?(?<-1>\1)+(?(1)^)。这使用平衡基团匹配长度为2或更大的回文。“所有重叠的比赛”部分有一个警告:每个开始位置最多只能进行一场比赛。但是,如果两个不同长度的回文从同一位置开始,则较短的回文将在较长的回文的末尾再次出现。而且由于+优先权的贪婪程度会更长,因此无论如何我们都会遇到所有回文。


2

05AB1E11 10字节

ŒÙʒÂQ}žQSK

在线尝试!



@scottinet对于单打而言失败,EG1234142141410010101000
魔术八爪鱼

1
您也一样,但方式不同。o_O正在发生一些需要调查的事情。同时,这是一个10字节的版本,似乎可以正常工作
scottinet

我解决了uniquify的一个错误。现在,您的11个字节的答案和我的9个字节的一个作品都::)
scottinet

@scottinet你10 byter可以通过改变是9 byter以及1›。:)
Kevin Cruijssen

1

Perl,112岁

$_=<>;chop;s/./$&$' /g;
map{/../&&$_ eq reverse&&$h{$_}++}split/ /
  for grep{s/./$`$& /g}split/ /;
print for keys %h

1

JavaScript(ES6),120字节

a=>{for(b=0,c=d=a.length,e=[];b<d;--c<b+2?(b++,c=d):1)(f=a.slice(b,c))==f.split``.reverse().join``&&e.push(f);return e}

该函数将字符串作为输入并输出一个数组。


1

Clojure,81个字节

#(set(for[i(range 2(+(count %)1))p(partition i 1 %):when(=(reverse p)(seq p))]p))

for在这里是一个完美的匹配:) :when(=(reverse p)p)如果输入是一个字符列表或一个完整的字符串不算作回文,则可以使用,实际上在这种情况下,最大范围也是i可以的(count %)

最紧凑的情况供参考:

#(set(for[i(range 2(count %))p(partition i 1 %):when(=(reverse p)p)]p))

1

Python,83 102个 字符

s=lambda t:(t[1:]or())and(t,)*(t==t[::-1])+s(t[1:])+s(t[:-1])
print set(s(input()))

这个短语(t[1:]or())and...相当于(...)if t[1:]else()并保存一个字符!有了节省,我对此感到非常自豪。

例:

python x
"51112232211161"
set(['11', '22', '11122322111', '161', '111', '112232211', '1223221', '22322', '232'])

1

斯卡拉127

object p extends App{val s=args(0);print(2.to(s.size).flatMap(s.sliding(_).toSeq.filter(c=>c==c.reverse)).toSet.mkString(" "))}

为了使这与Scala的其他答案相比,我也做了一个我自己的对象,该对象扩展了App。我没有手动迭代输入字符串并使用子字符串,而是利用了slide()为我创建了所有子字符串的序列。


1

斯卡拉156 170

object o extends App{val l=args(0).length-2;val r=for(i<-0 to l;j<-i to l;c=args(0).substring(i,j+2);if(c==c.reverse))yield c;print(r.toSet.mkString(" "))}

object o{def main(s:Array[String]){val l=s(0).length-2;val r=for(i<-0 to l;j<-i to l;c=s(0).substring(i,j+2);if(c==c.reverse)) yield c;println(r.distinct.mkString(" "))}}


嗨,Lalith,我将您的代码缩短了一点:在yield和扩展App之前没有空白,而不是覆盖main,println => print和distinct => toSet
用户未知

1

Perl 6的 35  32个字节

{unique m:ex/(.+).?<{$0.flip}>/}

测试一下

{set m:ex/(.+).?<{$0.flip}>/}

测试一下

展开:

{  # bare block lambda with implicit parameter 「$_」

  set             # turn into a Set object (ignores duplicates)

  \             # stringify 「~」 all of these 「«」 (possibly in parrallel)
                  # otherwise it would be a sequence of Match objects

  m               # match
  :exhaustive     # in every way possible
  /
    ( .+ )        # at least one character 「$0」
    .?            # possibly another character (for odd sized sub-palindromes)
    <{ $0.flip }> # match the reverse of the first grouping
  /
}



1

APL(Dyalog Classic),27字节

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)

在线尝试!

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)    Monadic train:
                                Enclose the input, '12131331'
                     ⍳∘≢          Range from 1 to length of input
                     ⍳∘≢,/¨⊂      List of list of substrings of each length
                   1            Remove the first list (length-1 substrings)
                ,/              Put the rest of the substrings into a single list.
{∪⍵/⍨≡∘⌽¨⍨⍵}                   To the result, apply this function which
                                   keeps all palindromes from a list:
      ≡∘⌽¨⍨⍵                    Boolean value of whether each (¨) string in argument
      ≡∘⌽                      is equal to its own reverse

  ⍵/⍨                           Replicate (filter) argument by those values.
                                 This yields the length >1 palindromes.
                                Remove duplicates from the list of palindromes.

由于OP要求输入“代码”,因此该代码段∪w/⍨≡∘⌽¨⍨w←⊃,/1↓(⍳∘≢,/¨⊂)有效。
亚当

@Adám我想我会保留这个答案,这是出于现代站点标准的考虑,尤其是因为它没有获得整体胜利。
lirtosiast

1

Japt,14个字节

Êò2@ãX fêSÃc â

在线尝试!

说明:

Êò2               #Get the range [2...length(input)]
   @      Ã       #For each number in that range:
    ãX            # Get the substrings of the input with that length
       fêS        # Keep only the palindromes
           c      #Flatten
             â    #Keep unique results

1

PowerShell,99字节

$args|% t*y|%{$s+=$_
0..$n|%{if($n-$_-and($t=-join$s[$_..$n])-eq-join$s[$n..$_]){$t}}
$n++}|sort -u

在线尝试!

少打高尔夫球:

$args|% toCharArray|%{
    $substring+=$_
    0..$n|%{
        if( $n-$_ -and ($temp=-join$substring[$_..$n]) -eq -join$substring[$n..$_] ){
            $temp
        }
    }
    $n++
}|sort -Unique

1

Brachylog,11个字节

{s.l>1∧.↔}ᵘ

在线尝试!

(发布时链接中的标题已损坏,因此,这是仅在第一个测试用例上的谓词(在Brachylog中与功能等效),w最后是a 来实际打印输出。)

               The output is
{        }ᵘ    a list containing every possible unique
 s.            substring of
               the input
   l           the length of which
    >          is greater than
     1         one
      ∧        and
       .       which
        ↔      reversed
               is itself. (implicit output within the inline sub-predicate)

我觉得有一种较短的方法可以检查长度是否大于1。(如果未过滤掉琐碎的回文,那就应该是{s.↔}ᵘ。)


1

APL(NARS),65个字符,130个字节

{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}

测试:

  r←{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
  o←⎕fmt
  o r '1234442'
┌2───────────┐
│┌2──┐ ┌3───┐│
││ 44│ │ 444││
│└───┘ └────┘2
└∊───────────┘
  o r '3333'
┌3───────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐│
││ 3333│ │ 333│ │ 33││
│└─────┘ └────┘ └───┘2
└∊───────────────────┘
  o r  "12131331"
┌5─────────────────────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐ ┌3───┐ ┌3───┐│
││ 1331│ │ 121│ │ 33│ │ 313│ │ 131││
│└─────┘ └────┘ └───┘ └────┘ └────┘2
└∊─────────────────────────────────┘
  o r '1234'
┌0─┐
│ 0│
└~─┘


{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
 y←⍵  assign the argument to y (because it has to be used inside other function)
 x←11 1‼k k⊢k←≢y   assign the lenght of y to k, call the function 11 1‼k k
                   that seems here find all partition of 1 2 ..k
 {x[⍵;]⊂y}¨⍳≢      make partition of arg ⍵ using that set x
 ∪/                set union with precedent to each element of partition y (i don't know if this is ok)
 b←↑               get first assign to b
 {1≥≢⍵:0⋄∧/⍵=⌽⍵}¨ for each element of b return 1 only if the argument ⍵ is such that 
                   "∧/⍵=⌽⍵" ⍵ has all subset palindrome, else return 0
 b/⍨               get the elements in b for with {1≥≢⍵:0⋄∧/⍵=⌽⍵} return 1
 m←∪               make the set return without ripetition element, and assign to m
 0=≢               if lenght of m is 0 (void set) than 
 :⍬⋄m              return ⍬ else return m

有人更清楚为什么会这样,并且可以更好地解释这一点,而无需对此进行任何更改...我不太确定这段代码,如果测试示例更多,可能会出问题...


1

Japt,9个字节

ã â fÅfêU

试试吧

ã â fÅfêU     :Implicit input of string
ã             :Substrings
  â           :Deduplicate
    f         :Filter elements that return truthy
     Å        :  Slice off first character
       f      :Filter elements that return true
        êU    :  Test for palindrome

0

Java 8,202 201 199字节

import java.util.*;s->{Set r=new HashSet();String x;for(int l=s.length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=s.substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);return r;}

在这里尝试。

如果不允许使用某个功能且需要完整的程序,则为256 255 253字节改为:

import java.util.*;interface M{static void main(String[]a){Set r=new HashSet();String x;for(int l=a[0].length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=a[0].substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);System.out.print(r);}}

在这里尝试。

说明:

import java.util.*;      // Required import for Set and HashSet

s->{                     // Method with String parameter and Set return-type
  Set r=new HashSet();   //  Return-Set
  String t;              //  Temp-String
  for(int l=s.length(),  //  Length of the input-String
          i=0,j;         //  Index-integers (start `i` at 0)
      i<l;i++)           //  Loop (1) from `0` to `l` (exclusive)
    for(j=i;++j<=l;)     //   Inner loop (2) from `i+1` to `l` (inclusive)
      if((t=s.substring(i,j) 
                         //    Set `t` to the substring from `i` to `j` (exclusive)
         ).contains(new StringBuffer(t).reverse())
                         //    If this substring is a palindrome,
         &t.length()>1)  //    and it's length is larger than 1:
        r.add(t);        //     Add the String to the Set
                         //   End of inner loop (2) (implicit / single-line body)
                         //  End of loop (1) (implicit / single-line body)
  return r;              //  Return the result-Set
}                        // End of method

0

JavaScript(ES6),107个字节

返回一个Set

s=>new Set((g=(s,r=[...s].reverse().join``)=>s[1]?(r==s?[s]:[]).concat(g(s.slice(1)),g(r.slice(1))):[])(s))

测试用例

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.