Chuỗi con duy nhất ngắn nhất


14

Cho (trên STDIN, dưới dạng đối số dòng lệnh hoặc làm đối số hàm) hai chuỗi không trống riêng biệt, tìm và trả về chuỗi con ngắn nhất của chuỗi thứ nhất không phải là chuỗi con của chuỗi thứ hai. Nếu không có chuỗi con như vậy tồn tại, bạn có thể trả về chuỗi trống, trả về bất kỳ chuỗi nào không phải là chuỗi con của chuỗi gốc hoặc ném ngoại lệ. Nếu bạn đang trở về từ một hàm, bạn cũng có thể trả về null (hoặc không xác định, Không có, v.v.) trong trường hợp này. Nếu nhiều chuỗi con như vậy được buộc trong thời gian ngắn nhất, bạn có thể trả lại bất kỳ một trong số chúng.

Chuỗi có thể bao gồm bất kỳ ký tự ascii có thể in.

Đầu vào được cung cấp trên STDIN sẽ được cung cấp với một chuỗi trên mỗi dòng. Theo yêu cầu của bạn, một dòng trống duy nhất có thể được thêm vào cuối đầu vào.

Đây là mã golf, vì vậy chương trình hợp lệ ngắn nhất sẽ thắng.

MỘT SỐ TRƯỜNG HỢP KIỂM TRA

ĐẦU VÀO:

STRING ONE
STRING TWO

ĐẦU RA:

E

ĐẦU VÀO:

A&&C
A&$C

ĐẦU RA GIÁ TRỊ:

&&
&C

ĐẦU VÀO:

(Hai chuỗi 80 chữ cái được tạo ngẫu nhiên)

QIJYXPYWIWESWBRFWUHEERVQFJROYIXNKPKVDDFFZBUNBRZVUEYKLURBJCZJYMINCZNQEYKRADRYSWMH
HAXUDFLYFSLABUCXUWNHPSGQUXMQUIQYRWVIXGNKJGYUTWMLLPRIZDRLFXWKXOBOOEFESKNCUIFHNLFE

TẤT CẢ CÁC ĐẦU RA GIÁ TRỊ:

AD
BJ
BR
CZ
DD
EE
ER
EY
EY
FF
FJ
FW
FZ
HE
IJ
IN
IW
JC
JR
JY
KL
KP
KR
KV
LU
MH
MI
NB
NQ
OY
PK
PY
QE
QF
QI
RA
RB
RF
RO
RV
RY
RZ
SW
UE
UH
UN
UR
VD
VQ
VU
WB
WE
WI
WU
XN
XP
YI
YK
YK
YM
YS
YW
YX
ZB
ZJ
ZN
ZV

1
ngắn nhất hay dài nhất?
Leaky Nun

@FryAmTheEggman Sau đó tôi vẫn nên đăng giải pháp của mình ...
Leaky Nun

"Một chuỗi trên mỗi dòng" có hoặc không có dấu ngoặc kép?
Leaky Nun

1
Chúng ta có thể lấy một chuỗi các chuỗi?
Dennis

"B" có phải là chuỗi con của "aBc" không?
downrep_nation

Câu trả lời:


4

Brachylog , 23 byte

:1foh.,{,.[A:B]hs?'~sB}

Hoạt động trên bộ chuyển đổi Java cũ. Yêu cầu hai chuỗi trong một danh sách làm đầu vào, thống nhất đầu ra với chuỗi con. Nếu không tìm thấy chuỗi con, trả về false.

Thật không may, tôi chưa mã hóa tập hợp con được tích hợp sẵn trong bộ chuyển mã Prolog mới.

Giải trình

:1f               Find all bindings which satisfy predicate 1 with that binding as input and
                  with the Input of the main predicate as output.
   oh.,           Order that list of bindings, and unify the output with the first one.

{
 ,.[A:B]          Unify the output with the list [A,B]
        hs?       Unify the input with a subset of A
           '~sB   Check that no subset of B can be unified with the input
               }

4

Con trăn, 119 115 91

lambda a,b:[a[m:m+n]for n in range(1,len(a)+1)for m in range(len(a))if a[m:m+n]not in b][0]

Các trường hợp thử nghiệm:

| Input 1  | Input 2     | Output        |
|----------+-------------+---------------|
| 'abcd'   | 'abc'       |  'd'          |
| 'abcd'   | 'dabc'      |  'cd'         |
| 'abcd'   | 'dcbabbccd' |  'abc'        |
| 'abcdf'  | 'abcdebcdf' |  'abcdf'      |
| 'abc'    | 'abc'       |  (IndexError) |

Làm việc để làm cho nó ngắn hơn, nhưng đây là bản năng não của tôi. Không thực sự nhiều của một tay golf chưa.

Cảm ơn @ user81655 và @NonlinearF nhung cho các byte bổ sung.

Chỉnh sửa :

Đăng. Đã thử mã này:

def z(a,b):
 for s in [a[m:m+n]for n in range(1,len(a)+1)for m in range(len(a)-n+1)]:
  if s not in b:return s
 return''

Nghĩ rằng nó ngắn hơn một vài byte. Hóa ra nó dài hơn 1 byte so với những gì tôi có trước khi chỉnh sửa.


Tôi không biết nhiều trăn, nhưng có lẽ bạn có thể làm (r=range)(1,len(a)+1)sau đó sử dụng r?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Không thể làm điều đó theo cách đó. Nếu tôi gán rangecho rdòng trên, nó thực sự thêm một byte. Ý tưởng tốt, mặc dù. Có lẽ có một cách ngắn hơn để lặp qua các chuỗi con.
Taylor Lopez

range(1,len(a))range(len(a)-1)có nên làm việc không? Ngoài ra tôi nghĩ rằng sử dụng một ký tự tab cho hai dấu cách không gian sẽ tiết kiệm một byte.
dùng81655

Không, với range(1,len(a)), lần thử thứ 4 không thành công vì nó sẽ không thử chuỗi đầy đủ; nó sẽ chỉ đi đến độ dài của chuỗi - 1. Và với range(len(a)-1), trường hợp thử nghiệm đầu tiên không trả về 'cd'thay vì chỉ 'd'. Có thể có một cái gì đó ở đó, mặc dù.
Taylor Lopez

Xin lỗi, tôi không quen với Python và tôi cho rằng phạm vi đã bao gồm. Trong trường hợp đó hãy thử range(1,len(a)+1)range(len(a)).
dùng81655

3

Python, 87 86 byte

lambda s,t,e=enumerate:[s[i:i-~j]for j,_ in e(s)for i,_ in e(s)if(s[i:i-~j]in t)<1][0]

Nếu nó tồn tại, điều này sẽ trả về ngoài cùng của tất cả các chuỗi con duy nhất ngắn nhất.

Nếu không có chuỗi con duy nhất, IndexError sẽ được nâng lên.

Kiểm tra nó trên Ideone .


Nó đây rồi Tôi đã chờ đợi ai đó giết chết việc thực hiện phi lambda của tôi. lol tốt đẹp
Taylor Lopez

Tôi nghĩ rằng bạn có thể làm ngắn này bằng cách cung cấp đối số thứ hai tùy chọn để enumeratekhởi động jtại i+1.
user2357112 hỗ trợ Monica

@ user2357112 Thật không may, ném NameError . Mã xác định jđầu tiên, sau đó i.
Dennis

@Dennis: Vâng, nhưng nó không cần. Bạn có thể chuyển đổi thứ tự vòng lặp.
user2357112 hỗ trợ Monica

1
@ user2357112 Nếu tôi chuyển đổi thứ tự vòng lặp, chuỗi con duy nhất đầu tiên mà nó tìm thấy có thể không phải là ngắn nhất. Đơn giản chỉ cần hoán đổi trả lại đơn hàng 'ab'cho đầu vào 'abc','aaa'.
Dennis

2

Python, 82 byte

g=lambda u:{u}|g(u[1:])|g(u[:-1])if u else{''}
f=lambda s,t:min(g(s)-g(t),key=len)

Cách sử dụng: f('A&&C', 'A&$C')-> trả về'&&'

Tăng ValueError nếu không có chuỗi con phù hợp.

Giải trình:

g=lambda u:{u}|g(u[1:])|g(u[:-1])if u else{''}đệ quy tạo một tập hợp các chuỗi con u f=lambda s,t:min(g(s)-g(t),key=len)lấy chuỗi con ngắn nhất từ ​​chênh lệch tập hợp


2

JavaScript (ES6), 79 byte

f=
(a,b)=>[...a].some((_,i,c)=>c.some((_,j)=>b.indexOf(s=a.substr(j,i+1))<0))?s:''
<div oninput=o.textContent=f(a.value,b.value)><input id="a"/><input id="b"/><pre id=o>

Nếu trả về falselà chấp nhận được, hãy lưu 2 byte bằng cách sử dụng &&sthay vì ?s:''.



1

JavaScript (Firefox), 80 byte

solution=

a=>b=>[for(_ of(i=0,a))for(_ of(j=!++i,a))if(b.includes(s=a.substr(j++,i)))s][0]

document.write("<pre>"+
[ [ "test", "best" ], [ "wes", "west" ], [ "red", "dress" ] ]
.map(c=>c+": "+solution(c[0])(c[1])).join`\n`)

Kiểm tra chỉ hoạt động trong Firefox. Trả về undefinednếu không có chuỗi con.


Các chuỗi có thể chứa các ký tự ASCII có thể in được như \ hoặc các siêu ký tự RegExp khác, nhưng nếu bạn tự giới hạn mình với Firefox, tại sao không sử dụng b.includesthay thế?
Neil

@Neil Câu hỏi không nói rằng các chuỗi có thể là bất kỳ ký tự nào trước đó nhưng cảm ơn vì đã cho tôi biết! Cập nhật để sử dụng includes.
dùng81655

1
Đoạn kiểm tra ném mộtSyntaxError: unexpected token 'for'
NoOneIsHãy

@NoOneIsĐây là lỗi bạn sẽ gặp nếu bạn không sử dụng Firefox ...
user81655

1

Võng mạc , 37 byte

M!&`\G(.+?)(?!.*¶.*\1)
O$#`.+
$.&
G1`

Đầu ra trống nếu không tìm thấy chuỗi con hợp lệ A.

Hãy thử trực tuyến!.

Giải trình

M!&`\G(.+?)(?!.*¶.*\1)

Đối với mỗi vị trí bắt đầu có thể trong A, khớp với chuỗi con ngắn nhất không xuất hiện B. Điều &này dành cho các trận đấu chồng chéo, sao cho chúng tôi thực sự thử mọi vị trí bắt đầu, ngay cả khi trận đấu dài hơn một ký tự. Việc \Gđảm bảo rằng chúng tôi không bỏ qua bất kỳ vị trí nào - đặc biệt, theo cách này, chúng tôi phải dừng lại ở nguồn cấp dữ liệu, để chúng tôi không nhận được các kết quả bổ sung từ Bchính nó. Lý do điều này không làm mọi thứ rối tung lên thực sự khá tinh tế: bởi vì nếu có một vị trí bắt đầu trong Ađó chúng ta không thể tìm thấy bất kỳ chuỗi con hợp lệ nào, thì đó cũng là một thất bại sẽ khiến \Gviệc dừng kiểm tra thêm bất kỳ vị trí nào. Tuy nhiên, nếu (từ vị trí bắt đầu hiện tại), tất cả các chuỗi con xuất hiện trongB, vì vậy tất cả các chuỗi con bắt đầu xa hơn của vị trí hiện tại, vì vậy loại bỏ chúng không phải là vấn đề (và thực sự cải thiện hiệu suất).

Do M!cấu hình, tất cả các trận đấu này sẽ được trả về từ giai đoạn, được nối với các nguồn cấp dữ liệu.

O$#`.+
$.&

Điều này sắp xếp các dòng của kết quả trước theo chiều dài. Điều này được thực hiện bằng cách khớp dòng với .+. Sau đó $kích hoạt một dạng "sắp xếp", sao cho trận đấu được thay thế bằng cách $.&xác định thứ tự sắp xếp. Bản $.&thân nó thay thế trận đấu với chiều dài của nó. Cuối cùng, #tùy chọn yêu cầu Retina sắp xếp số (nếu không, nó sẽ coi các số kết quả là chuỗi và sắp xếp chúng theo từ vựng).

G1`

Cuối cùng, chúng tôi chỉ đơn giản giữ dòng đầu tiên, bằng cách sử dụng giai đoạn grep với regex trống (luôn khớp) và giới hạn 1.


1

Perl, 87 85

sub{(grep{$_[1]!~/\Q$_/}map{$}=$_;map{substr($_[0],$_,$})}@}}(@}=0..length$_[0]))[0]}

Đây là một hàm ẩn danh trả về đầu tiên (theo vị trí) của các chuỗi con ngắn nhất $_[0]không xảy ra $_[1]hoặc undefnếu không có chuỗi con như vậy tồn tại.

Chương trình thử nghiệm với các chuỗi được lấy từ câu trả lời của @ iAmMortos, được thử nghiệm với Perl 5.22.1:

#!/usr/bin/perl -l
use strict;
use warnings;

my $f = <see above>;
print $f->('abcd', 'abc');
print $f->('abcd', 'dabc');
print $f->('abcd', 'dcbabbccd');
print $f->('abcdf', 'abcdebcdf');
print $f->('abc', 'abc');

1

Haskell, 72 byte

import Data.Lists
a#b=argmin length[x|x<-powerslice a,not$isInfixOf x b]

Ví dụ sử dụng: "abcd" # "dabc"-> "cd".

Một cách thực hiện đơn giản: xây dựng tất cả các chuỗi con avà giữ những thứ không xuất hiện trong đó b. argmintrả về một phần tử của danh sách làm giảm thiểu hàm cho đối số thứ 2, tại đây : length.


Tôi không biết về argmin! Có vẻ như vô cùng hữu ích.
Zgarb

0

Pyth - 9 6 byte

h-Fm.:

Hãy thử trực tuyến tại đây .


Vượt qua 9 vẫn là 9
mèo

Tôi muốn biết làm thế nào điều này hoạt động.
mroman

@mroman the .: với một arg là tất cả các chất nền. Vì vậy, tôi ánh xạ rằng trên cả hai chuỗi, sau đó gập setwise diff, vì vậy tôi có tất cả các chất nền đầu tiên không phải là thứ hai, sau đó tôi chọn chuỗi đầu tiên, là số nhỏ nhất: được sắp xếp.
Maltysen

0

C #, 152 byte

string f(string a,string b){int x=a.Length;for(int i=1;i<=x;i++)for(int j=0;j<=x-i;j++){var y=a.Substring(j,i);if(!b.Contains(y))return y;}return null;}

0

Ruby, 70 byte

Thu thập tất cả các chuỗi con có độ dài nhất định từ chuỗi thứ nhất và nếu có chuỗi không có trong chuỗi thứ hai, hãy trả lại chuỗi đó.

->a,b{r=p;(1..l=a.size).map{|i|(0...l).map{|j|b[s=a[j,i]]?0:r||=s}};r}

0

Burlesque - 26 byte

Ngay bây giờ cách ngắn nhất tôi có thể nghĩ ra là:

lnp^sujbcjz[{^p~[n!}f[-][~

0

Japt , 14 byte

Êõ!ãU c k!èV g

Hãy thử trực tuyến!

Trả về undefinednếu không có chuỗi con hợp lệ . Điều này khác với việc trả về chuỗi "không xác định" , mặc dù sự khác biệt chỉ hiển thị do cờ -Q.

Giải trình:

Ê                 :Length of the first input
 õ                :For each number in the range [1...length]:
  !ãU             : Get the substrings of the first input with that length
      c           :Flatten to a single array with shorter substrings first
        k         :Remove ones which return non-zero to:
         !èV      : Number of times that substring appears in second input
             g    :Return the shortest remaining substring

0

Japt -h, 11 byte

à f@øX «VøX

Thử nó

                :Implicit input of strings U & V
à               :All combinations of U
  f@            :Filter each as X
    øX          :  Does U contain X?
       «        :  Logical AND with the negation of
        VøX     :  Does V contain X?
                :Implicit output of last element
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.