Phép trừ chuỗi


37

Mục tiêu

Tạo một hàm để đảo ngược chuỗi nối

Đầu vào

Hai chuỗi (chữ và số + dấu cách), trong đó một chuỗi nên được trừ cho chuỗi kia.

  • Bạn có thể giả định rằng chuỗi được trừ sẽ không bao giờ lớn hơn chuỗi khác.

Đầu ra

Kết quả của phép trừ

Phép trừ

Bạn nên xóa một chuỗi từ đầu hoặc cuối chuỗi khác. Nếu chuỗi có mặt ở đầu và cuối, bạn chỉ có thể xóa một chuỗi, chuỗi nào sẽ bị xóa tùy thuộc vào bạn.
Nếu chuỗi không bắt đầu hoặc kết thúc hoặc không khớp chính xác, đó là phép trừ không hợp lệ và bạn nên xuất chuỗi gốc.

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

Phép trừ hợp lệ

'abcde','ab' -> 'cde'
'abcde','cde' -> 'ab'
'abab','ab' -> 'ab'
'abcab','ab' -> 'abc' or 'cab'
'ababcde','ab' -> 'abcde'
'acdbcd','cd' -> 'acdb'
'abcde','abcde' -> ''
'abcde','' -> 'abcde'
'','' -> ''

Phép trừ không hợp lệ (trả về chuỗi gốc)

'abcde','ae' -> 'abcde'
'abcde','aa' -> 'abcde'
'abcde','bcd' -> 'abcde'
'abcde','xab' -> 'abcde'
'abcde','yde' -> 'abcde'

Đầu vào không hợp lệ (không cần xử lý)

'','a' -> ''

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


4
Tại sao kết quả của trường hợp đầu tiên không cde? Bạn có ý nghĩa gì bởi hợp lệ? Chúng ta có cần phải đánh giá tính hợp lệ của đầu vào không, hay bạn có nghĩa là chúng ta sẽ không nhận được đầu vào không hợp lệ?
Leaky Nun

7
Chết tiệt 'abcde','bcd' -> 'abcde', vì đã phá vỡ giải pháp của tôi
John Dvorak

5
Chúng ta có thể giả sử các chuỗi sẽ an toàn regex (chữ và số + dấu cách) không?
John Dvorak

2
Tôi muốn đề nghị 'ababcde', 'ab''abcde'như một trường hợp thử nghiệm. Một số thuật toán ngây thơ thất bại trên đó.

2
@Rod Bạn có thể cân nhắc việc thử lại thử thách "Nối chuỗi ngược"?
MD XF

Câu trả lời:


19

Java 8, 46 45 44 40 byte

-1 byte nhờ TheLethalCoder

-1 byte vì tôi bị câm (cảm ơn Rod!)

-4 byte nhờ Kevin Cruijssen

a->b->a.replaceFirst("^"+b+"|"+b+"$","")

Hãy thử trực tuyến! (bao gồm tất cả các trường hợp thử nghiệm)

Một câu trả lời Java thực sự đánh bại một vài ngôn ngữ thực tế khác. Mỉm cười. (và bây giờ nó đánh bại JS!)


Sử dụng currying để lưu một bytea->b->
TheLethalCoder

@TheLethalCoder Cảm ơn.
Okx

Tại sao bạn để lại trong hashmap không sử dụng trong ví dụ trực tuyến của bạn?
Michael

Bạn có thể thay đổi Firstđể Allcho -2 byte. Bởi vì ^$nó luôn luôn ở cuối hoặc bắt đầu Chuỗi, vì vậy ngay cả với replaceAllnó chỉ thay thế nó một lần. Hãy thử nó ở đây. PS: Tôi đã thêm số đếm byte trước đó vào câu trả lời của bạn, đây là điều thường được thực hiện sau khi chỉnh sửa mã golf ở đây trên PPCG.
Kevin Cruijssen

@KevinCruijssen Tôi biết về các cuộc đình công, đoán tôi chỉ quên lần này. Tuy nhiên, nếu tôi sử dụng Allthay vì First, điều này trở thành sự thật:"abab" + "ab" -> ""
Okx

9

JavaScript (ES6), 41 byte

s=>t=>s.replace(eval(`/^${t}|${t}$/`),'')

Đưa đầu vào thông qua cú pháp currying, tức là f("abab")("ab").


3
Bây giờ, tại sao tôi chưa bao giờ nghĩ sẽ sử dụng eval()để xây dựng RegExes trước đây?!
Xù xì

9

Brachylog (Dùng thử trực tuyến!), 12 byte

~cpĊh.∧Ċtw|w

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

Lấy chuỗi để trừ khỏi đầu vào tiêu chuẩn và chuỗi để trừ làm đối số dòng lệnh.

Giải trình

~cpĊh.∧Ċtw|w
~c            Split {the input} into pieces
  p           and (possibly) rearrange those pieces
   Ċ          such that there are two pieces
    h         and the first
     .        matches the command line argument
      ∧       then
         w    print
        t     the last
       Ċ      piece.
          |   If all else fails,
           w  print {the input}.


6

JavaScript (ES6), 76 70 45 41 byte

s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")

Thử nó

f=
s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")
o.innerText=f(i.value="abcde")(j.value="ab")
i.oninput=j.oninput=_=>o.innerText=f(i.value)(j.value)
<input id=i><input id=j><pre id=o>


2
Bạn không cần new .
lập trình

@ lập trình500, tôi đã từ bỏ công việc này khi thấy phiên bản của ETH! : D Cập nhật ngay. Cảm ơn.
Xù xì

4

Perl 6 , 21 byte

->$_,$b {S/^$b|$b$//}

Thử nó

Mở rộng:

-> $_, $b {   # pointy block lambda

  S/          # Str replace and return (implicitly against 「$_」)

  |   ^ $b    # starting with the second argument
  |     $b $  # or ending with the second argument

  //          # replace with nothing.

}


3

TI-Basic (TI-84 Plus CE), 63 byte

Prompt Str0,Str2
inString(Str0,Str2
If Ans
sub(Str0,1,Ans-1)+sub(Str0,Ans+length(Str2),length(Str0)-Ans+1-length(Str2→Str0
Str0

Tôi có một câu hỏi, tại sao bạn không sử dụng Str1 như một biến?
Zacharý

@ Zacharý Tôi nghĩ rằng tôi đã có một cái gì đó được lưu trữ trong đó tại thời điểm đó. Tôi thực sự không nhớ.
pizzapants184

Điều gì Ansthậm chí không đề cập đến trên dòng thứ tư?
Zacharý

@ Zacharý Ansđề cập đến giá trị được đánh giá cuối cùng, vì vậy trong trường hợp này, nó đề cập đến giá trị được trả về bởi inString(, đó là chỉ số của chuỗi con Str2trong chuỗi Str0hoặc 0 nếu chuỗi con không xuất hiện. Một câu lệnh if không sửa đổi giá trị của Ans, vì vậy trên dòng thứ tư, chỉ mục vẫn còn Ans.
pizzapants184

Ồ, tôi quên cách inStringlàm việc. Chơi golf tốt
Zacharý

3

Toán học, 162 byte

(c=Characters;a=c@#;b=c@#2;l=Length;t={};If[l@Intersection[a,b]==l@b,If[MemberQ[Partition[a,l@b,1],b],t=a;Table[t=DeleteCases[t,b[[i]],1,1],{i,l@b}]],t=a];""<>t)&

kiểm tra kiểu đầu vào ["abcde", "ab"]


1
Giải pháp tốt đẹp! Bạn có thể lưu một byte bằng cách sử dụng #thay vì #1- chúng có nghĩa chính xác như nhau. Ngoài ra, thay vì sử dụng StringJoin@t, bạn có thể gian lận bằng cách nối một chuỗi trống với chuỗi ""<>t, nó cũng tự động kết hợp mọi thứ tvới nhau. Bạn đã xem trang mẹo chơi golf Mathicala chưa?
Không phải là một cái cây vào

Có một vài điều nữa bạn có thể làm để lưu byte (chẳng hạn, tôi nghĩ bạn không cần xác định t={};ngay từ đầu), nhưng có thể dễ dàng hơn khi sử dụng một cách tiếp cận khác hoàn toàn - bạn đã thử sử dụng StringReplacechức năng?
Không phải là cây

Bạn được phép lấy một chuỗi Chuỗi làm đầu vào, vì vậy bạn không thực sự cầnc=Characters;a=c@#;b=c@#2;
JungHwan Min

Ngoài ra, l@Intersection[a,b]l[a∩b].
JungHwan Min


3

Bash ,66 61 49 byte

case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac

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

ít chơi gôn

a=$1;
case $1 in 
    *$2)  c=${a%$2};;       
    $2*)  c=${a#$2};;
      *)  c=$1;;
esac;
echo $c

Sử dụng trường hợp để kiểm tra bắt đầu hoặc kết thúc, và tiền tố mảng / hậu tố (% / #) mảng


1
Sử dụng tốt đẹp case, nhưng lâu hơn cần thiết. Mẫu thứ 2 và thứ 3 có thể được hợp nhất thành một mẫu duy nhất : *)c=${1#$2};;. Sau đó, chỉ với 2 nhánh sẽ ngắn hơn với echomỗi nhánh thay vì sử dụng biến $c: case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac. Hoặc bạn có thể tiếp tục sử dụng nó, nhưng không có case: c=${1%$2};[[ $c = $1 ]]&&c=${1#$2};echo $c.
thao tác

3

APL (Dyalog) , 31 30 byte

-1 cảm ơn Zacharý .

Điều này thực sự sử dụng phép nối ngược (tức là nghịch đảo)! Lấy chuỗi gốc làm đối số bên trái và những gì cần trừ làm đối số bên phải.

{0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}

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

Ung dung:

{
    0::⍺{          if an error happens, apply the following function on the arguments
        0::⍺           if an error happens, return the left argument unmodified
        ,∘⍵⍣¯1⊢⍺       inverse-append right argument on left argument
        }⍵
    ⍵,⍣¯1⊢⍺       inverse-prepend the right argument on the left argument
}

Huyền thoại:

{... } chức năng ẩn danh

 đối số bên trái của hàm hiện tại

 đối số đúng của hàm hiện tại

0::Nếu có lỗi xảy ra, hãy thực hiện điều này, khác

⍣¯1⊢ nghịch đảo

,∘⍵ nối bên phải

⍵, nối bên trái


Tôi nghĩ bạn có thể lưu một byte với {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý

@ Zacharý Vâng, cảm ơn.
Adám



2

Haskell , 49 byte

f s a b|s==b=a|a/=b,h:t<-a=f(s++[h])t b|1<3=s
f""

Hãy thử trực tuyến! Cách sử dụng : f"" "abcdef" "ab". Cách khác, xác định (-)=f""và sử dụng như thế nào "abcdef" - "ab".

Giải pháp không có regex này hoạt động bằng cách phân chia đệ quy chuỗi trong tất cả các tiền tố và hậu tố của nó và kiểm tra xem chuỗi được trừ có khớp với một trong số chúng không.



1

C #, 88 byte

s=>r=>s.StartsWith(r)?s.Substring(r.Length):s.EndsWith(r)?s.Substring(0,s.IndexOf(r)):s;

Biên dịch thành a Func<string, Func<string, string>>.


1

Ruby (biểu thức lambda), 29 byte

->a,b{a.sub /^#{b}|#{b}$/,""}

Yay cho nội suy regex! Yêu cầu các ẩn phụ an toàn regex, nhưng điều đó không sao theo thách thức.


1

Tcl , 37 byte

proc s {a b} {regsub "^$b|$b$" $a {}}

Hãy thử trực tuyến! (hiện đang chạy tất cả các bài kiểm tra)

Tcl là đơn giản. proc s {a b}định nghĩa một hàm có tên stham số ab. regsubthay thế {}, là một chuỗi rỗng, cho giá trị bkhi nó ở đầu hoặc cuối của a. Sự trở lại là ngầm.


1

C, 96 byte

Đó là kiến ​​thức phổ biến rằng thao tác chuỗi trong C là cồng kềnh, vì việc chơi gôn mở rộng sẽ là đường biên giới. Âm thanh ổn với tôi.

f(a,b,t,l)char**a,*b,*t;{t=*a;l=strlen(b);bcmp(t,b,l)?bcmp(t+=strlen(t)-l,b,l)||(*t=0):(*a+=l);}

Một trong những chương trình ít đọc hơn tôi đã viết. Có hai đầu vào (mặc dù hàm trông như thế nào), một char**trỏ đến chuỗi để deconcatenate và một char*chuỗi là chuỗi cần loại bỏ. Con trỏ đầu vào được chỉnh sửa tại chỗ và trở thành đầu ra (ai cũng bị rò rỉ bộ nhớ).

Ví dụ sử dụng:

char *a = malloc(6);
strcpy(a, "abcde");
char *b = malloc(4);
strcpy(b, "abc");
f(&a,b);
printf("%s\n", a); // "de"

1

AWK , 21 32 byte

{sub("^"$2"|"$2"$",z,$1);$0=$1}1

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

Trình gốc ban đầu thay thế văn bản trong chuỗi đầu tiên, không chỉ ở đầu hoặc cuối.

{sub($2,z,$1);$0=$1}1

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

Ban đầu đã thử mà không có dấu ngoặc nhọn, nhưng nó yêu cầu các thủ thuật để in ra các dòng trống và không khớp mà cuối cùng đã thêm nhiều byte hơn phiên bản này.


1

R, 20 42 41 byte

pryr::f(sub(sprintf('^%s|%s$',b,b),'',a))

-1 byte nhờ MickyT!

Trả về một hàm ẩn danh (có các đối số theo thứ tự b,a). Tính toán sự khác biệt chuỗi a-b. sublà một sự thay thế đơn giản hoán đổi sự xuất hiện đầu tiên của mẫu với, trong trường hợp này là chuỗi rỗng ''. Xây dựng biểu thức chính quy sprintfđể chỉ khớp ở đầu và cuối chuỗi. Yêu cầu pryrgói phải được cài đặt.

Trên liên kết TIO, sử dụng function(a,b)định nghĩa dài hơn cho hàm cho bốn byte nữa.

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


1
Còn 'abcde','bcd' -> 'abcde'trường hợp thì sao?
Jonathan Allan

" subLà một thay thế đơn giản rằng chỉ cần hoán đổi sự xuất hiện đầu tiên của bnăm a": Sẽ trao đổi này nếu chuỗi thứ hai là ở giữa của chuỗi đầu tiên?
TheLethalCoder

Tôi đọc sai câu hỏi! Rất tiếc. Cảm ơn đã bắt nó!
Giuseppe

bạn có thể lấy lại 1 byte vớisprintf('^%s|%s$',b,b)
MickyT

@MickyT, cảm ơn! đã sửa.
Giuseppe

1

Lisp thông thường, 121 byte

(lambda(x y)(cond((equal(#1=subseq x 0 #3=(length y))y)(#1#x #3#))((equal(#1#x #2=(-(length x)#3#))y)(#1#x 0 #2#))(t x)))

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

Lisp thông thường thường gặp!

Phiên bản bị đánh cắp:

(defun f(x y)
  (cond ((equal (subseq x 0 (length y)) y)               ; if x starts with y
         (subseq x (length y)))                          ; return rest of x
        ((equal (subseq x (- (length x) (length y))) y)  ; if x ends with x
         (subseq x 0 (- (length x) (length y))))         ; return first part of x
        (t x)))                                          ; else return x

1

Kotlin , 91 byte

{a,b->val v=b.length
if(a.startsWith(b))a.drop(v)else if(a.endsWith(b))a.dropLast(v)else a}

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


? {a,b->var c=a.removePrefix(b);if(a==c){c=a.removeSuffix(b)};c}
mê mẩn

@mazzy cảm thấy tự do để gửi đó là câu trả lời của riêng bạn.
ốc_

1

Powershell, 34 40 byte

+6 byte khi Invalid Subtraction thêm trường hợp kiểm tra

param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"

Bình luận:

Biểu thức regrec ^$t|$t$ không hoạt động như mong đợi: nó thay thế cả hai trận đấu thay vì một (cờ gluôn bật). Vì vậy, chúng tôi buộc phải sử dụng nhóm nhìn tiêu cực.

Kịch bản thử nghiệm:

$f = {
    param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"
}

@(
    ,('abcde','ab', 'cde')
    ,('abcde','cde', 'ab')
    ,('abab','ab', 'ab')
    ,('abcab','ab', 'abc', 'cab')
    ,('ababcde','ab', 'abcde')
    ,('acdbcd','cd', 'acdb')
    ,('abcde','abcde', '')
    ,('abcde','', 'abcde')
    ,('','', '')

    ,('abcde','ae', 'abcde')
    ,('abcde','aa', 'abcde')
    ,('abcde','bcd', 'abcde')
    ,('abcde','xab', 'abcde')
    ,('abcde','yde', 'abcde')

    ,('','a', '')
) | % {
    $s,$t,$e = $_
    $r = &$f $s $t
    "$($r-in$e): $r"
}

Đầu ra:

True: cde
True: ab
True: ab
True: abc
True: abcde
True: acdb
True:
True: abcde
True:

0

QBIC , 57 byte

Whegh, đây là một mớ hỗn độn trong QBIC / QBasic ...

B=@ `+B┘x=instr(;,;)~x|?_t_sB,x-1|+_sB,x+_lC|,_lB|||\?B

B=@ `+B          Prepend a string to B$. Thisis a hack to avoid errors with 
                 removing substrings stating at index 1
┘                Line-break in QBasic output
       (;,;)     Read the string (B$) and the to-be-removed substring (C$)
x=instr          And make x to be the starting index of the first C$ in B$
~x|              IF X <> 0 (ie C$ is present in B$)
?                PRINT
 _t                trimmed version (drops the prepended space)
  _sB,x-1|+        of a substring from 1 to x (the start of C$) -1
  _sB,x+_lC|,_lB   and the rest of the string, starting after C$
                     _l takes the length of a string
  |||              End TRIM, end Substring, end Length
\?B              When missing C$, just print B$


0

Tôi ban đầu đọc sai hướng dẫn. Cảm ơn, Ørjan Johansen đã chỉ ra sai lầm của tôi!

PowerShell , 46 51 byte

Function F($o,$a){([regex]"^$a").replace($o,'',1);}

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


Điều này không thành công trong trường hợp 'abcde' 'bcd'.
Ørjan Johansen

Tôi đang thấy kết quả mong đợi từ trường hợp thử nghiệm đó - TIO tại đây
Jeff Freeman

Đây là trường hợp thử nghiệm được liệt kê của OP và kết quả sẽ là abcde- bcdkhông xảy ra ở hai đầu của chuỗi.
Ørjan Johansen

Bạn nói đúng. Tôi đọc sai hướng dẫn. Cảm ơn đã chỉ ra điều đó!
Jeff Freeman

0

Excel, 129 byte

=IFERROR(IF(FIND(B1,A1)=1,SUBSTITUTE(A1,B1,"",1),IF(FIND(B1,A1,LEN(A1)-LEN(B1))>LEN(A1)-LEN(B1),LEFT(A1,LEN(A1)-LEN(B1)),A1)),A1)

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.