2 개 문자열의 가장 긴 공통 접두사


30

2 개의 문자열을 입력으로 사용하고 가장 긴 공통 접 두부를 리턴하는 프로그램을 작성하십시오. 이것은 이므로 가장 짧은 바이트 수의 응답이 이깁니다.

Test Case 1:

"global" , "glossary"
"glo"


Test Case 2:

"department" , "depart"
"depart"

Test Case 3:

"glove", "dove"
""

1
또 다른 좋은 테스트 사례는 "aca", "aba"입니다.
Morgan Thrapp

2
STDIN에서 입력하여 STDOUT으로 인쇄하거나 기능이 정상인 완전한 프로그램을 원하십니까?
xnor

2
입력에 줄 바꿈이 없다고 가정 할 수 있습니까? 입력 한 문자는 무엇입니까?
Downgoat

5
일반 사항 : 정규식 기반 솔루션을 사용하는 사람은 다른 사람의 정규식 답변을 직접 테스트하지 않고 복사해서는 안됩니다. 모든 정규식 엔진에서 작동하지는 않습니다. 특히, 그것은 nvi와 vim에서 다른 (올바르지 않은) 답변을 제공합니다.
Random832

1
주어진 모든 예제는 소문자이지만 대소 문자 구분에 대해 걱정해야합니까? 예를 들어, should globaland GLOSSARYreturn glo또는 ''?
AdmBorkBork

답변:


22

파이썬 3, 54 바이트

이 작업을위한 내장 함수를 가지고있는 Python에게 감사합니다! :디

import os;print(os.path.commonprefix(input().split()))

같은 공백으로 구분 된 두 단어로 입력을받습니다 glossary global.


21

하스켈, 29 바이트

(c:x)%(d:y)|c==d=c:x%y;_%_=""

용법:

>> "global"%"glossary"
"glo"

%패턴 일치를 통해 이진 함수 를 재귀 적으로 정의합니다 . 첫 글자가 같은 두 줄에서 첫 글자를 가져 와서 나머지 문자열의 함수 앞에 붙입니다. 다른 것에 빈 문자열을 제공합니다.


11

Pyth, 8 7 바이트

e@F._MQ

1 바이트 할인을 위해 @isaacg에게 감사드립니다.

따옴표와 쉼표로 구분하여 입력을 "abc", "acc"받습니다. 결과가 빈 문자열이면 오류가 발생하지만 stdout은 비워 둡니다. 허용되지 않는 경우 2 바이트를 추가하십시오.#e@F._MQq

테스트 스위트

설명

e@F._MQ        : implicit Q = eval(input)
   ._MQ        : Map the prefix operator onto both inputs
 @F            : Fold the setwise intersection operator over those lists
e              : Take the last such element, the prefixes are always made from shortest
               : to longest, so this always gives the longest matching prefix

결과를 오류없이 빈 문자열로 만들려면 : e|@F._M.z]k.
kirbyfan64sos

@ kirbyfan64sos은 내가 그것을 주변에 대해에 넣은 것을 믿는 #...q한 바이트 이하보다, 내가이 전체 코드에서 편집거야, 난 그 혼란 생각
FryAmTheEggman

1
형식으로 입력하고 대신 "abc", "def"사용할 수 있습니다Q.z
isaacg

10

C ++, 101 (100) 99 바이트

#include<iostream>
int i;main(){std::string s,t;std::cin>>s>>t;for(;s[i]==t[i];std::cout<<s[i++]);}

에서 두 개의 문자열을 읽고 stdin현재 문자열의 한 위치에서 현재 위치의 문자를 인쇄하고 현재 위치의 문자는 다른 문자열의 동일한 위치에있는 문자와 같습니다.

1 바이트를 저장 한 Zereges 에게 감사합니다 .


4
그것은 그 for진술을 아름답고 끔찍하게 사용하는 것입니다.
Joshpbarron

문자열이 같으면 루프가 종료되지 않습니다.
Jon Trauntvein

2
공백이 포함 된 문자열에는 작동하지 않습니다. int i전역 공간 을 만들어 1 바이트를 절약 할 수 있습니다 (0으로 초기화 됨)
Zereges

@JonTrauntvein 그 사건은 UB (?)라고 생각합니다. 그것은 나를 위해 작동합니다. (gcc-5.1)
sweerpotato

9

하스켈, 38 바이트

((map fst.fst.span(uncurry(==))).).zip

사용 예 : ( ((map fst.fst.span(uncurry(==))).).zip ) "global" "glossary"-> "glo".

두 입력 문자열을 문자 쌍 목록으로 압축하십시오. 두 개의 목록을 작성하십시오. 두 문자가 같으면 처음부터 모든 쌍을 가진 첫 번째 목록과 나머지는 모두 두 번째 목록입니다. 두 번째 목록을 삭제하고 첫 번째 목록에서 모든 문자를 추출하십시오.


9

CJam, 12 11 9 바이트

l_q.-{}#<

이것은 유닉스 스타일의 줄 끝이있는 두 개의 개별 줄에서 문자열을 읽습니다 <string>\n<string>\n.

-1 바이트의 경우 @ MartinBüttner와 -2 바이트의 경우 @ jimmy23013에게 감사합니다!

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

l_         e# Read a line (w/o trailing LF) from STDIN and push a copy.
  q        e# Read another line from STDIN (with trailing LF).
           e# The trailing linefeed makes sure that the lines are not equal.
   .-      e# Perform vectorized character subtraction. This yields 0 for equal
           e# characters, a non-zero value for two different characters, and the
           e# characters themselves (truthy) for the tail of the longer string.
     {}#   e# Find the index of the first truthy element.
        <  e# Keep that many characters from the first string.

Darn, 나는 나의 첫 번째 대답이 너무 가깝다는 것을 믿을 수 없다!
geokavel

1
후행 줄 바꿈을 가정하고 약간을 속여서 사용할 수 있습니다 l_q.-.
jimmy23013

@ jimmy23013 그것은 유닉스 계열 OS의 입력 표준입니다. 왜 그렇지 않습니까? 감사!
Dennis

8

APL, 13

{⊃↓K/⍨=⌿K←↑⍵}

이것은 두 문자열의 배열을 취하고 접두사를 반환하는 함수입니다.

      {⊃↓K/⍨=⌿K←↑⍵}'glossary' 'global'
glo
      {⊃↓K/⍨=⌿K←↑⍵}'department' 'depart'
depart

APL 알파벳이 바이트 크기 문자의 알파벳이라고 말하는 것이 정말 공평합니까? 아니면이 표준 관행이 여기에 있습니까?
Filipq

9
@Filipq 여기서 답변은 언어에 가장 자연스러운 인코딩을 사용합니다. APL에는 각 문자가 단일 바이트 인 자체 코드 페이지가 있습니다.
Alex A.

7

AppleScript, 215 바이트

그리고 나는 열심히 노력했습니다 ...; (

x를 (디스플레이 대화 상자 ""기본 답변 "")의 텍스트로 반환
to (display dialog ""default answer "")의 텍스트를 반환하도록 설정
n을 1로 설정
o를 ""로 설정
x의 항목 n = a의 항목 n 동안 반복
o를 o & x의 항목 n으로 설정
n을 n + 1로 설정
종료
영형

나는 AppleScript로이 해낼 수있는 방법을 잘보고 싶어하고, 남자 는없는 문자열 비교를 위해 내장되어 있습니다.


12
AppleScript는 아무것도 만들지 않았습니다 .
kirbyfan64sos

내가 끔찍한 골프 외에 내가 그것을 사용하는 유일한 것입니다 tell app "System Events" to <something>. 이다 하지만, 그것은 이런 종류의 물건을 다루는 방식을 볼 수 재미. @ kirbyfan64sos
애디슨 크럼프



6

CJam, 12 8 26

r:AAr:B.=0#_W={;;ABe<}{<}?

온라인으로 사용해보십시오.

(Dennis의 답변을 본 후 .- 대신. =를 사용하는 것이 좋습니다.)

모든 엣지 케이스로 인해 나와 같은 CJam 초보자는 짧게 유지하기가 어려워졌습니다. 바라건대, 이것은 적어도 모든 경우에 효과가 있습니다.


6

C #, 201 147 바이트

using System.Linq;class a{static void Main(string[]a){a[0].Take(a[1].Length).TakeWhile((t,i)=>a[1][i]==t).ToList().ForEach(System.Console.Write);}}

나는 그것이 경쟁이 심하지 않다는 것을 안다. 나는 그것이 어떻게 생겼는지보고 싶었습니다.

편집 : 감사합니다 Ash Burlakzenko, Berend 및 Dennis_E


2
250 바이트 미만의 C # 응답을 얻는 것만으로도 경쟁이 치열합니다. 또한, 당신은 단지 할 수 using System.*없습니까?
박수 :

1
.ForEach(x=>Console.Write(x))단축 할 수.ForEach(Console.Write)
재 Burlaczenko

1
using System.Collections.Generic;불필요합니다. 에서 공백을 제거하여 하나 이상의 바이트를 제거하십시오 string[] a.
Berend

2
1- Contains불필요합니다. 2- 이 코드는 제거 using System;하고 System.Console.Write;"aab", "aaab"입력에 대해 잘못된 결과 ( "a")를 반환하여 몇 바이트를 절약 할 수 있습니다 IndexOf. 내가 생각할 수있는 가장 짧은 수정은 다음을 사용하는 것입니다. a[0].Take(a[1].Length)147 바이트 길이입니다. "System.Linq; class a {static void Main (string [] a) {a [0] .Take (a [1] .Length) .TakeWhile 사용 ((c, i) => a [1] [i] == c) .ToList (). ForEach (System.Console.Write);}} "
Dennis_E

휴식을 취할 때 의견을 보내 주셔서 감사합니다. 특히 Dennis_E의 의견을 잘 살펴 보겠습니다.
Jakotheshadows

5

커먼 리스프, 39

(lambda(a b)(subseq a 0(mismatch a b)))

두 개의 문자열 인수를 사용하여 서로 다른 인덱스 i를 결정하고 0에서 i 까지의 하위 문자열을 반환합니다 .


5

펄 5, 20 19 18 바이트

19 바이트에 -E플래그 대신 1을 더한 값 -e:

say<>=~/^(.*).* \1/

이것은 Digital Traumased answer 에서 뻔뻔스럽게 복사되었습니다 . 입력은 공백이없는 (또는 첫 번째 전에) 두 단어 사이에 공백이있는 두 단어라고 가정합니다.


최신 정보:

-pe바이트를 저장하기 위해 다음과 같이 사용하지 않는 것이 좋습니다 (감사합니다!) :

($_)=/^(.*).* \1/

그런 다음 Luk Storms-nE다음과 같이 다른 바이트를 저장하도록 제안했습니다 (감사합니다!).

say/^(.*).* \1/

(나는 믿는다 -E한 바이트 대신에 표준으로 -e하지만, -n또는 -p두 가지로. 내 느낌은 그 주변 SOP를 점입니다.)


1
" -M5.010필요한 경우 무료입니다" . 동일한 메타 포스트 당 -pe또는 -ne2 perl -nE 'say/^(.*).* \1/'가 아닌 1 바이트가 추가되므로 16 바이트를 얻습니다.
ThisSuitIsBlackNot

4

파이썬 3, 72

FryAmTheEggman 덕분에 31 바이트가 절약되었습니다. DSM 덕분에 8 명이 저장되었습니다.

r=''
for x,y in zip(input(),input()):
 if x==y:r+=x
 else:break
print(r)

파이썬 프로그래머가 없으면 zip무엇을할까요? : D
베타 부패

7
@BetaDecay 우리의 비행은 항상 열려있을 것입니다.
Morgan Thrapp

input()s를 넣고 및 바인딩을 zip저장할 수 있습니다. ab
DSM

@DSM Ooo, 좋은 지적입니다. 감사!
Morgan Thrapp

4

파이썬 3, 47

def f(w):[print(end=c[c!=d])for c,d in zip(*w)]

w두 단어 의 목록을 가져 와서 오류로 끝나기 전에 공통 접두사를 인쇄 하는 함수입니다 .

Python 3의 print기능을 사용하면 서로 플러시 문자열을 인쇄 할 수 있습니다 print(end=c)(이 짧은 구문으로 3 바이트를 절약하는 Sp3000 덕분). 이것은 단어에서 두 글자를 반복적으로 받아 첫 글자를 인쇄합니다. 인덱싱 c[c!=d]은 범위를 벗어난 오류를 발생시킵니다. 여기서 c!=d두 개의 다른 문자가 발견되면 실행이 종료됩니다.

명시 적 for 루프는 목록 이해보다 1 자 긴 것입니다.

def f(w):
 for c,d in zip(*w):print(end=c[c!=d])

와우! 나는 함수 사용에 대해 생각조차하지 않았다! 좋은데 +1
Zach Gates

지금 이걸 보았지만 어떻 print(end=c[c!=d])습니까?
Sp3000

1
@ Sp3000 와우, print선택 사항이라는 주요 인수가 end 인수로만 호출 할 수 있고 문자열을 포함 할 수 있다는 것을 결코 연결하지 않았습니다 . 그것은 일반적으로 정말 유용한 트릭입니다. 당신은 팁을 만들어야합니다.
xnor

3

자바 스크립트 ES6, 52 바이트

f=(a,b)=>[...a].filter((e,i)=>e==b[i]?1:b='').join``

용법:

>> f("global","glossary")
"glo"

작동하지 않습니다 ada,aca...
flawr

맞아요. 문자열이 더 이상 일치하지 않으면 필터링을 종료하는 것을 잊었습니다.
Dendrobium

1
함수의 이름을 지정할 필요가 없으므로f=
Ypnypn

1
지도로 더 작게 할 수 있습니다(a,b)=>[...a].map((e,i)=>e==b[i]?e:b='').join``
Shaun H

2

레티 나 , 14 바이트

kirbyfan64sos 와 동일한 아이디어를 사용합니다 . 불행히도, 결국 매치 모드는 캡처 그룹을 인쇄하는 방법을 제공한다고 Martin의 주장에도 불구하고 아직 구현되지 않았습니다. 그렇지 않으면 (.*).* \1아직 존재하지 않는 구성 문자열 옵션에 대해 2 바이트와 함께 사용할 수 있습니다.

(.*).* \1.*
$1

Each line would go in its own file, with 1 byte added per additional file. Alternatively, run in a single file with the -s flag.


The equivalent regex fails to match in vim due to greediness (and a non-greedy regex will match the shortest substring, i.e. blank), are you sure it works?
Random832

@Random832 Try using this regex replace tester, with the .NET option checked. Set the operation to "replace", and put the patterns in the correct boxes. It doesn't fail to match if there should be one. How could it possible fail due to greediness? That's the only reason it works. \1 ensures that both words start with the same prefix. So no matter how greedy (.*) is, \1 is the same.
mbomb007

In vim it refuses to match at all - I think it is finding a longer string for the first (.*), then failing to match it against \1, then not properly backtracking to shorter strings.
Random832

@Random832 Then you need to find something else to test your regexes on.
mbomb007

2

K, 24 bytes

{(+/&\=/(&/#:'x)#'x)#*x}

Find the minimum of the length of each string. ((&/#:'x)). Trim each string to that length (#'x). Then compare, smear and sum the resulting sequence:

  =/("globaa";"glossa")
1 1 1 0 0 1
  &\=/("globaa";"glossa")
1 1 1 0 0 0
  +/&\=/("globaa";"glossa")
3

Finally, take that many characters from the first of the strings provided (#*x).

In action:

 f: {(+/&\=/(&/#:'x)#'x)#*x};
 f'(("global";"glossary")
    ("department";"depart")
    ("glove";"dove")
    ("aaa";"aaaaa")
    ("identical";"identical")
    ("aca";"aba"))
("glo"
 "depart"
 ()
 "aaa"
 "identical"
 ,"a")

2

Powershell, 65 bytes

Compare the strings, shrinking the first until it either matches (print and exit) or the string is null and the loop terminates.

param($a,$b)while($a){if($b-like"$a*"){$a;exit}$a=$a-replace".$"}

2

Julia, 62 bytes

f(a,b)=(c="";for(i,j)=zip(a,b) i!=j?break:(c*=string(i))end;c)

Ungolfed:

function f(a::AbstractString, b::AbstractString)
    # Initialize an output string
    c = ""

    # Iterate over the pairs of characters in a and b,
    # truncated to the shorter of the two lengths
    for (i, j) in zip(a, b)
        if i == j
            # If they match, append to the output string
            c *= string(i)
        else
            # Otherwise stop everything!
            break
        end
    end

    return c
end

Fixed an issue (at the hefty cost of 14 bytes) thanks to xnor!


2

C99, 73 bytes

main(int c,char *a[]){for(char *x=a[1],*y=a[2];*x==*y++;putchar(*x++));}

Similar to this answer, but shorter and meets spec (takes input from stdin).


Spec doesn't say input has to come from stdin. This is actually longer than the other answer if you add #include<stdio.h>, which is necessary for the program to compile.
musarithmia

@AndrewCashner - It doesn't need to be on stdin, but it does need to take input. The other answer is hard-coded. Also, gcc whines about the implicit usage, but it compiles fine without the include.
Comintern

Much shorter without the temporaries: main(int c,char**a){for(;*a[1]==*a[2]++;putchar(*a[1]++));} (59 bytes).
Toby Speight

2

MATLAB, 50 40 bytes

Defines a function that accepts 2 strings as input, outputs to command window

function t(a,b);a(1:find([diff(char(a,b)) 1],1)-1)

This solution will work for any string, outputs

ans =

   Empty string: 1-by-0

if no match is given.

Can be golfed by using a script instead of a function (using local variables a, b) (-16 bytes).

so getting 34 Bytes

a(1:find([diff(char(a,b)) 1],1)-1)

The function style (which seems to be the accepted style), yields

@(a,b)a(1:find([diff(char(a,b)) 1],1)-1)

(Thanks @Stewie Griffin)


40 bytes: @(a,b)a(1:find([diff(char(a,b)) 1],1)-1). =)
Stewie Griffin

2

Perl 6, 28 bytes

I came up with two that take their values from STDIN which are based on the Perl 5 answer.

lines~~/(.*).*' '$0/;say ~$0
lines~~/:s(.*).* $0/;say ~$0

The first requires exactly one space between the inputs, while the other requires at least one whitespace character between the inputs.


That is quite a bit shorter than the first thing I tried which takes the values from the command line.

say [~] map ->($a,$b){$a eq$b&&$a||last},[Z] @*ARGS».comb # 58 bytes

or even the lambda version of it:

{[~] map ->($a,$b){$a eq$b&&$a||last},[Z] @_».comb} # 52 bytes

Though this is much easier to adjust so that it accepts any number of input strings, at the cost of only one stroke.

{[~] map ->@b {([eq] @b)&&@b[0]||last},[Z] @_».comb} # 53 bytes
#          ┗━┛ ┗━━━━━━━┛  ┗━━━┛
my &common-prefix = {[~] map ->@b {([eq] @b)&&@b[0]||last},[Z] @_».comb}

say common-prefix <department depart>; # "depart"
say common-prefix; # ""
say common-prefix <department depart depot deprecated dependant>; # "dep"

# This code does not work directly with a single argument, so you have
# to give it an itemized List or Array, containing a single element.

say common-prefix $('department',); # "department"

# another option would be to replace `@_` with `(@_,)`

2

Japt, 27 bytes

Japt is a shortened version of JavaScript. Interpreter

Um$(X,Y)=>$A&&X==VgY ?X:A=P

(The strings go into the Input box like so: "global" "glossary")

This code is exactly equivalent to the following JS:

A=10;(U,V)=>U.split``.map((X,Y)=>A&&X==V[Y]?X:A="").join``

I have not yet implemented anonymous functions, which is what the $...$ is for: anything between the dollar signs is left untouched in the switch to JS. After I add functions, this 21-byte code will suffice:

UmXY{A&&X==VgY ?X:A=P

And after I implement a few more features, it will ideally be 18 bytes:

UmXY{AxX=VgY ?X:AP

Suggestions welcome!


So it turns out that this program is only 15 bytes in modern Japt:

¡A©X¥VgY ?X:A=P

Try it online!


2

MATL, 11 9 bytes

y!=XdYpf)

Try it online!

(-2 bytes thanks to Giuseppe)

 y  % implicitly input the two strings, then duplicate the
    %  first one into the stack again
    %  stack: ['department' 'deported' 'department']
 !  % transpose the last string into a column vector
 =  % broadcast equality check - gives back a matrix comparing
    %  every letter in first input with the letters in the second
 Xd % diagonal of the matrix - comparison result of each letter with
    %  only corresponding letter in the other string
    %  stack: ['department' [1; 1; 1; 0; 1; 1; 0; 0;]]
 Yp % cumulative product (so only initial sequence of 1s remains
    %  1s, others become 0)
    %  stack: ['department' [1; 1; 1; 0; 0; 0; 0; 0;]]
 f  %  find the indices of the 1s
 )  % index at those elements so we get those letters out
    % (implicit) convert to string and display

Thanks! The y idea is pretty good, I'd tried things like an initial iti instead of the 1Gw, but didn't think of using the y for that.
sundar - Reinstate Monica

1

Clojure/ClojureScript, 51

(defn f[[a & b][c & d]](if(= a c)(str a(f b d))""))

Pretty straightforward. Unfortunately the spaces around the parameter destructuring are necessary (that's the [a & b] stuff). Not the shortest but I beat some other answers in languages that like to brag about their terseness so I'll post it.


1

Python 2, 50 bytes

for a,b in zip(*input()):print(1/0if a!=b else a),

Input

The input is taken as two strings:

"global", "glossary"

Output

The output is each character followed by a space; which, hopefully, isn't a problem. However, if it is, I'll edit my answer.

g l o 

I'm pretty sure this is invalid; the spec clearly gave the output format as a string without spaces.
lirtosiast

Well yes, but the input was also given in the format "global" , "glossary" (two separate strings).. How many other answers follow that to the letter? @ThomasKwa
Zach Gates

"takes two strings" is the language used by OP; usually when something like that is mentioned without any qualifiers, it refers to one of our default I/O, which means we can take one string from the command line and one from STDIN, or an array of two strings, or whatever else follows those rules.
lirtosiast

I think you're taking my answer a bit too seriously. This is just a fun submission and my best attempt at beating a built-in. If OP doesn't like the output format, so be it; I'll remove my answer. @ThomasKwa
Zach Gates

How about print(exit()if a!=b else a,end='')? I don't know if that'll work or not, but it might
Beta Decay

1

TeaScript, 16 bytes 20

xf»l¦y[i]?1:b=0)

Takes each input separated by a space.


1

PHP, 52 bytes

Not spectacular but does the job:

$a=$argv;while($a[1][$i]==$a[2][$i])echo$a[1][$i++];

Takes two command line arguments:

php prefix.php department depart

PHP7 lets you save another byte while(($a=$argv)[1][$i]==$a[2][$i])echo$a[1][$i++]; - Another PHP7 only solution (and best I could come up with @ 50 bytes) <?=substr(($a=$argv)[1],0,strspn($a[1]^$a[2],~ÿ)); - Make sure your editor is in ascii mode, it's important the ~ÿ does not get converted to unicode.
Leigh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.