Pengurangan string


37

Objektif

Buat fungsi untuk membalikkan rangkaian senar

Memasukkan

Dua string (spasi + alfanumerik), di mana satu harus dikurangkan untuk yang lain.

  • Anda dapat mengasumsikan bahwa string yang akan dikurangkan tidak akan pernah lebih besar dari yang lainnya.

Keluaran

Hasil dari pengurangan

Pengurangan

Anda harus menghapus satu string dari awal atau akhir dari string lain. Jika string ada di awal dan di akhir, Anda hanya dapat menghapus satu, yang mana yang akan dihapus terserah Anda.
Jika string tidak di awal atau di akhir, atau tidak sama persis, itu adalah pengurangan yang tidak valid dan Anda harus menampilkan string asli.

Uji Kasus

Pengurangan Valid

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

Pengurangan Tidak Valid (mengembalikan string asli)

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

Masukan Tidak Valid (tidak perlu ditangani)

'','a' -> ''

Ini adalah , jadi kode terpendek dalam byte menang!


4
Mengapa hasil dari kasus pertama tidak cde? Apa yang Anda maksud dengan valid? Apakah kita perlu menilai validitas input, atau maksud Anda bahwa kami tidak akan menerima input yang tidak valid?
Leaky Nun

7
Sialan kau,, 'abcde','bcd' -> 'abcde'karena melanggar solusiku
John Dvorak

5
Bisakah kita menganggap string akan aman-regex (alfanumerik + spasi)?
John Dvorak

2
Saya sarankan 'ababcde', 'ab''abcde'sebagai test case. Beberapa algoritma naif gagal pada yang satu itu.

2
@Rod Anda mungkin mempertimbangkan untuk mengulang tantangan "Rangkaian string terbalik"?
MD XF

Jawaban:


19

Java 8, 46 45 44 40 byte

-1 byte terima kasih kepada TheLethalCoder

-1 byte karena saya bodoh (terima kasih Rod!)

-4 byte terima kasih kepada Kevin Cruijssen

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

Cobalah online! (termasuk semua kasus uji)

Jawaban Java sebenarnya mengalahkan beberapa bahasa praktis lainnya. Senyum. (dan sekarang ini mengalahkan JS!)


Gunakan currying untuk menyimpan bytea->b->
TheLethalCoder

@TheLethalCoder Terima kasih.
Okx

Mengapa Anda meninggalkan hashmap yang tidak digunakan dalam contoh online Anda?
Michael

Anda dapat mengubah Firstke Alluntuk -2 byte. Karena itu ^dan $selalu baik di akhir atau mulai dari String, jadi bahkan dengan replaceAllitu hanya menggantinya sekali. Coba di sini. NB: Saya menambahkan byte-count sebelumnya yang dicolokkan ke jawaban Anda, yang biasanya dilakukan setelah mengedit kode-golf di PPCG.
Kevin Cruijssen

@KevinCruijssen Saya tahu tentang strike-through, kira saya baru saja lupa kali ini. Namun, jika saya menggunakan Allsebagai gantinya First, ini menjadi benar:"abab" + "ab" -> ""
Okx

9

JavaScript (ES6), 41 byte

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

Mengambil input melalui sintaks currying, yaitu f("abab")("ab").


3
Sekarang, mengapa saya tidak pernah berpikir untuk menggunakan eval()untuk membangun RegExes sebelumnya ?!
Shaggy

9

Brachylog (Coba Online!), 12 byte

~cpĊh.∧Ċtw|w

Cobalah online!

Mengambil string untuk mengurangi dari input standar, dan string untuk mengurangi sebagai argumen baris perintah.

Penjelasan

~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}$`),"")

Cobalah

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
Anda tidak perlu new .
programmer5000

@ programmer500, saya agak menyerah mengerjakan ini ketika saya melihat versi ETH! : D Diperbarui sekarang. Terima kasih.
Shaggy

4

Perl 6 , 21 byte

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

Cobalah

Diperluas:

-> $_, $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

Saya punya pertanyaan, mengapa Anda tidak menggunakan Str1 sebagai variabel?
Zacharý

@ Zacharý Saya pikir saya memiliki sesuatu yang tersimpan di sana pada saat itu. Saya tidak begitu ingat.
pizzapants184

Apa yang Ansbahkan merujuk pada baris keempat?
Zacharý

@ Zacharý Ansmerujuk pada nilai terakhir yang dievaluasi, jadi dalam hal ini mengacu pada nilai yang dikembalikan oleh inString(, yang merupakan indeks substring Str2dalam string Str0atau 0 jika substring tidak muncul. Pernyataan if tidak mengubah nilai Ans, jadi pada baris keempat indeks masih masuk Ans.
pizzapants184

Oh, saya lupa bagaimana cara inStringkerjanya. Golf yang bagus!
Zacharý

3

Mathematica, 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)&

uji gaya masukan ["abcde", "ab"]


1
Solusi bagus! Anda dapat menyimpan byte dengan menggunakan #alih-alih #1- artinya sama persis. Selain itu, alih-alih menggunakan StringJoin@t, Anda dapat menipu dengan menggabungkan string kosong dengannya ""<>t, yang secara otomatis menggabungkan semuanya tjuga. Pernahkah Anda melihat halaman kiat golf Mathematica ?
Bukan pohon

Ada beberapa hal lagi yang dapat Anda lakukan untuk menghemat byte (saya pikir Anda tidak perlu mendefinisikan t={};di awal, misalnya), tetapi mungkin lebih mudah untuk menggunakan pendekatan yang berbeda sama sekali - sudahkah Anda mencoba menggunakan StringReplacefungsi?
Bukan pohon

Anda diizinkan mengambil array String sebagai input, sehingga Anda tidak benar-benar perluc=Characters;a=c@#;b=c@#2;
JungHwan Min

Juga, l@Intersection[a,b]adalah l[a∩b].
JungHwan Min


3

Pesta ,66 61 49 byte

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

Cobalah online!

kurang golf:

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

Menggunakan case untuk menguji awal atau akhir, dan menyusun substraksi prefix / suffix (% ​​/ #)


1
Penggunaan yang bagus case, tetapi lebih lama dari yang diperlukan. 2 dan pola-3 dapat digabungkan ke dalam satu: *)c=${1#$2};;. Kemudian dengan hanya 2 cabang akan lebih pendek untuk echosetiap langsung daripada menggunakan variabel $c: case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac. Atau Anda bisa tetap menggunakannya, tetapi tanpa case: c=${1%$2};[[ $c = $1 ]]&&c=${1#$2};echo $c.
manatwork

3

APL (Dyalog) , 31 30 byte

-1 terima kasih kepada Zacharý .

Ini sebenarnya menggunakan concatenation terbalik (yaitu kebalikan dari)! Mengambil string asli sebagai argumen kiri, dan apa yang harus dikurangi sebagai argumen benar.

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

Cobalah online!

Tidak Disatukan:

{
    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
}

Legenda:

{... } fungsi anonim

 argumen kiri dari fungsi saat ini

 argumen yang benar dari fungsi saat ini

0::... jika ada kesalahan terjadi, jalankan ini, kalau tidak ...

⍣¯1⊢ terbalik

,∘⍵ menyatukan di sebelah kanan

⍵, menyatukan di sebelah kiri


Saya pikir Anda dapat menyimpan byte dengan {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý

@ Zacharya Ya, terima kasih.
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""

Cobalah online! Penggunaan: f"" "abcdef" "ab". Atau, tentukan (-)=f""dan gunakan like "abcdef" - "ab".

Solusi bebas regex ini bekerja dengan membelah string secara rekursi di semua pre-dan postfixes-nya dan memeriksa apakah string yang akan dikurangi cocok dengan salah satunya.



1

C #, 88 byte

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

Kompilasi ke a Func<string, Func<string, string>>.


1

Ruby (ekspresi lambda), 29 byte

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

Yay untuk interpolasi regex! Membutuhkan subtrahends aman-regex, tapi tidak apa-apa sesuai tantangan.


1

Tcl , 37 byte

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

Cobalah online! (sekarang menjalankan semua tes)

Tcl sangat mudah. proc s {a b}mendefinisikan fungsi bernama syang mengambil parameter adan b. regsubpengganti {}, yang merupakan string kosong, untuk nilai bkapan pada awal atau akhir a. Pengembaliannya implisit.


1

C, 96 byte

Sudah menjadi rahasia umum bahwa manipulasi string dalam C rumit, karena golf ekstensi akan menjadi garis batas masokis. Kedengarannya baik bagi saya.

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);}

Salah satu program yang kurang mudah dibaca yang saya tulis. Mengambil dua input (terlepas dari bagaimana fungsi terlihat), char**menunjuk ke string untuk didekonsiliasi dan achar* yang merupakan string untuk dihapus. Pointer input diedit di tempat dan menjadi output (yang peduli tentang kebocoran memori pula).

Contoh penggunaan:

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

Cobalah online!

Pengiriman asli secara naif menggantikan teks dalam string pertama, bukan hanya pada awal atau akhir.

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

Cobalah online!

Awalnya mencoba tanpa kawat gigi, tetapi diperlukan trik untuk mencetak garis kosong dan atau tidak cocok yang akhirnya menambahkan lebih banyak byte daripada versi ini.


1

R, 20 42 41 byte

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

-1 byte terima kasih kepada MickyT!

Mengembalikan fungsi anonim (yang memiliki argumen dalam urutan b,a). Menghitung perbedaan string a-b. subadalah substitusi sederhana yang menukar kemunculan pertama pola dengan, dalam hal ini, string kosong ''. Bangun regex dengan sprintfuntuk mencocokkan hanya pada awal dan akhir string. Membutuhkan pryrpaket untuk diinstal.

Pada tautan TIO, gunakan function(a,b)definisi yang lebih verbose untuk fungsi selama empat byte lebih.

Cobalah online!


1
Bagaimana dengan 'abcde','bcd' -> 'abcde'kasingnya?
Jonathan Allan

"Apakah subsubstitusi sederhana yang hanya menukar kejadian pertama bin a": Apakah ini swap jika string kedua berada di tengah-tengah string pertama?
TheLethalCoder

Saya salah membaca pertanyaan! Ups. Terima kasih telah menangkap itu!
Giuseppe

Anda bisa mendapatkan 1 byte kembali dengansprintf('^%s|%s$',b,b)
MickyT

@MickyT, terima kasih! tetap.
Giuseppe

1

Common Lisp, 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)))

Cobalah online!

Common Lisp yang biasa!

Versi tidak disatukan:

(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}

Cobalah online!


? {a,b->var c=a.removePrefix(b);if(a==c){c=a.removeSuffix(b)};c}
mazzy

@ mazzy merasa bebas untuk mengirimkannya sebagai jawaban Anda sendiri.
snail_

1

Powershell, 34 40 byte

+6 byte saat Invalid Subtractiontest case ditambahkan

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

Komentar:

Ekspresi regexp ^$t|$t$tidak berfungsi seperti yang diharapkan: ia menggantikan kedua kecocokan alih-alih satu (ditandai gselalu aktif). Jadi, kami terpaksa menggunakan grup lookahead negatif.

Skrip uji:

$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"
}

Keluaran:

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

0

QBIC , 57 byte

Whegh, ini berantakan di 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

Saya awalnya salah membaca instruksi. Terima kasih, Ørjan Johansen karena menunjukkan kesalahan saya!

PowerShell , 46 51 byte

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

Cobalah online!


Ini gagal pada kasus 'abcde' 'bcd'.
Ørjan Johansen

Saya melihat hasil yang diharapkan dari test case - TIO di sini
Jeff Freeman

Ini adalah test case terdaftar dari OP dan hasilnya seharusnya abcde- bcdtidak terjadi di kedua ujung string.
Ørjan Johansen

Anda benar. Saya salah membaca instruksi. Terima kasih telah menunjukkannya!
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)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.