String-Subtraktion

37

Zielsetzung

Erstellen Sie eine Funktion zum Umkehren der Zeichenfolgenverkettung

Eingang

Zwei Zeichenfolgen (alphanumerisch + Leerzeichen), wobei eine für die andere subtrahiert werden soll.

  • Sie können davon ausgehen, dass die zu subtrahierende Zeichenfolge niemals größer als die andere sein wird.

Ausgabe

Das Ergebnis aus der Subtraktion

Subtraktion

Sie sollten eine Zeichenfolge vom Anfang oder Ende einer anderen Zeichenfolge entfernen. Wenn die Zeichenfolge am Anfang und am Ende vorhanden ist, können Sie nur eine entfernen. Welche Zeichenfolge entfernt wird, liegt bei Ihnen.
Wenn die Zeichenfolge nicht am Anfang oder am Ende steht oder nicht exakt übereinstimmt, ist die Subtraktion ungültig und Sie sollten die ursprüngliche Zeichenfolge ausgeben.

Testfälle

Gültige Subtraktion

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

Ungültige Subtraktion (gibt die ursprüngliche Zeichenfolge zurück)

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

Ungültige Eingabe (muss nicht bearbeitet werden)

'','a' -> ''

Das ist , also gewinnt der kürzeste Code in Bytes!

Stange
quelle
4
Warum ist das Ergebnis des ersten Falls nicht cde? Was meinst du mit gültig? Müssen wir die Gültigkeit der Eingabe beurteilen oder meinen Sie, dass wir keine ungültigen Eingaben erhalten?
Undichte Nonne
7
Verdammt, dass du 'abcde','bcd' -> 'abcde'meine Lösung gebrochen hast
John Dvorak
5
Können wir davon ausgehen, dass die Zeichenfolgen regex-sicher sind (alphanumerisch + Leerzeichen)?
John Dvorak
2
Ich würde 'ababcde', 'ab''abcde'als Testfall vorschlagen . Einige naive Algorithmen schlagen in diesem Fall fehl.
2
@Rod Vielleicht überlegst du, die Herausforderung "String-Verkettung umkehren" erneut zu betiteln?
MD XF

Antworten:

19

Java 8, 46 45 44 40 Bytes

-1 Byte dank TheLethalCoder

-1 Byte, weil ich dumm bin (danke Rod!)

-4 Bytes dank Kevin Cruijssen

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

Probieren Sie es online! (beinhaltet alle Testfälle)

Eine Java-Antwort schlägt tatsächlich einige andere praktische Sprachen. Lächelt. (Und jetzt schlägt es JS!)

Okx
quelle
Nutze a->b->
currying
@TheLethalCoder Danke.
Ok,
Warum haben Sie in Ihrem Online-Beispiel die unbenutzte Hashmap verlassen?
Michael
Sie können das ändern , Firstum Allfür -2 Bytes. Aufgrund des ^und steht $es immer entweder am Ende oder am Anfang des Strings, replaceAllersetzt ihn also auch damit nur einmal. Probieren Sie es hier aus. PS: Ich habe die vorangegangenen durchgestrichenen Byte-Zählungen zu Ihrer Antwort hinzugefügt, was normalerweise nach Code-Golf-Änderungen hier bei PPCG der Fall ist.
Kevin Cruijssen
@ KevinCruijssen Ich wusste von den Durchschlägen, schätze, ich habe diese Zeit nur vergessen. Wenn ich jedoch Allanstelle von verwende First, wird dies wahr:"abab" + "ab" -> ""
Ok,
9

JavaScript (ES6), 41 Byte

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

Übernimmt Eingaben über die Currysyntax, d f("abab")("ab"). H.

ETHproductions
quelle
3
Warum habe ich noch nie daran gedacht, eval()RegExes zu erstellen ?!
Shaggy
9

Brachylog (Online testen !), 12 Byte

~cpĊh.∧Ċtw|w

Probieren Sie es online!

Subtrahiert die Zeichenfolge von der Standardeingabe und subtrahiert die Zeichenfolge als Befehlszeilenargument.

Erläuterung

~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}.

quelle
6

JavaScript (ES6), 76 70 45 41 Byte

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

Versuch es

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>

Zottelig
quelle
2
Das brauchst du nicht new .
programmer5000
@ programmer500, ich habe aufgehört, daran zu arbeiten, als ich die Version der ETH gesehen habe! : D Jetzt aktualisiert. Vielen Dank.
Shaggy
4

Perl 6 , 21 Bytes

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

Versuch es

Erweitert:

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

}
Brad Gilbert b2gills
quelle
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
Pizzapants184
quelle
Ich habe eine Frage, warum haben Sie Str1 nicht als Variable verwendet?
Zacharý
@ Zacharý Ich glaube, ich hatte damals etwas drin. Ich erinnere mich nicht wirklich.
Pizzapants184
Was steht Ansüberhaupt in der vierten Zeile?
Zacharý
@ Zacharý Ansbezieht sich auf den zuletzt ausgewerteten Wert, in diesem Fall also auf den von zurückgegebenen Wert inString(, der der Index der Teilzeichenfolge Str2in der Zeichenfolge ist, Str0oder auf 0, wenn die Teilzeichenfolge nicht angezeigt wird. Eine if-Anweisung ändert den Wert von Ans nicht. In der vierten Zeile befindet sich der Index also noch Ans.
Pizzapants184
Oh, ich habe vergessen, wie es inStringfunktioniert hat. Schönes Golf!
Zacharý
3

Mathematica, 162 Bytes

(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)&

Testeingabestil ["abcde", "ab"]

J42161217
quelle
1
Schöne lösung! Sie können ein Byte speichern, indem Sie #anstelle von verwenden #1- sie bedeuten genau dasselbe. Anstatt zu verwenden StringJoin@t, können Sie auch schummeln, indem Sie eine leere Zeichenfolge damit verbinden ""<>t, wodurch automatisch auch alles tzusammengefügt wird. Haben Sie die Seite mit den Mathematica-Golftipps gesehen ?
Kein Baum
Es gibt noch ein paar Dinge, die Sie tun können, um Bytes zu sparen (ich glaube, Sie müssen zum Beispiel nicht zu t={};Beginn definieren ), aber es könnte einfacher sein, einen völlig anderen Ansatz zu verwenden - haben Sie versucht, die zu verwenden StringReplaceFunktion?
Kein Baum
Sie dürfen ein String-Array als Eingabe verwenden, damit Sie es nicht wirklich benötigenc=Characters;a=c@#;b=c@#2;
JungHwan Min
Auch l@Intersection[a,b]ist l[a∩b].
JungHwan Min
3

Python, 69 68 64 57 51 45 Bytes

Dies war eine völlig andere Lösung für Regex.

Danke an Value Ink für -2 Bytes!
und Felipe Nardi Batista für die massiven -6 Bytes!

import re
lambda s,c:re.sub(c+'$|^'+c,'',s,1)

Probieren Sie es online!

Artyer
quelle
Für -2 Bytes:re.sub(c.join("^|$"),'',s,1)
Wert Tinte
1
Für -6 Bytes:c+'$|^'+c
Felipe Nardi Batista
3

Bash ,66 61 49 Bytes

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

Probieren Sie es online!

weniger golfen:

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

Verwendet case zum Testen von Anfang oder Ende und der Subtraktion von Array-Präfix / Suffix (% ​​/ #)

marcosm
quelle
1
Gute Verwendung case, aber länger als nötig. Die 2. und 3. Muster könnte zu einem einzigen zusammengefasst werden: *)c=${1#$2};;. Dann mit nur 2 Zweige wären kürzer echojeweils direkt anstelle der Verwendung von variablen $c: case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac. Oder Sie könnten halten Sie es, aber ohne case: c=${1%$2};[[ $c = $1 ]]&&c=${1#$2};echo $c.
manatwork
3

APL (Dyalog) , 31 30 Bytes

-1 danke an Zacharý .

Dies verwendet tatsächlich die umgekehrte Verkettung! Nimmt den Originalstring als linkes Argument und was als rechtes Argument zu subtrahieren ist.

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

Probieren Sie es online!

Ungolfed:

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

Legende:

{} Anonyme Funktion

 linkes Argument der aktuellen Funktion

 richtiges Argument der aktuellen Funktion

0::… Falls ein Fehler auftritt, führe diesen aus, sonst…

⍣¯1⊢ invers

,∘⍵ verketten auf der rechten Seite

⍵, verketten auf der linken Seite

Adam
quelle
Ich denke, Sie können ein Byte mit retten {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý
@ Zacharý Ja, danke.
Adám
2

PHP, 54 Bytes

[,$x,$y]=$argv;echo preg_replace("#^$y|$y$#","",$x,1);

Testfälle

Jörg Hülsermann
quelle
2

Python 2 , 68 Bytes

def f(s,c):v=len(c);print[s[v:],s[:-v],s][[s[:v],s[-v:],c].index(c)]

Probieren Sie es online!

Jonathan Allan
quelle
2

Haskell , 49 Bytes

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

Probieren Sie es online! Verbrauch: f"" "abcdef" "ab". Alternativ definieren (-)=f""und verwenden Sie like "abcdef" - "ab".

Bei dieser Lösung ohne regulären Ausdruck wird die Zeichenfolge in alle Vor- und Nachfixes rekursiv aufgeteilt und überprüft, ob die zu subtrahierende Zeichenfolge mit einer dieser Zeichenfolgen übereinstimmt.

Laikoni
quelle
2

Python 2 , 72 65 Bytes

a,b=input()
l=len(b)
print[[a,a[:-l]][b==a[-l:]],a[l:]][b==a[:l]]

Probieren Sie es online!

-7 Bytes dank @FelipeNardiBatista

ovs
quelle
golfed
Felipe Nardi Batista
@FelipeNardiBatista vielen Dank!
Ovs
1

88 Bytes

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

Kompiliert zu a Func<string, Func<string, string>>.

TheLethalCoder
quelle
1

Rubin (Lambda-Ausdruck), 29 Bytes

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

Yay für Regex-Interpolation! Benötigt regex-sichere Subtrahenden, aber das ist gemäß der Herausforderung in Ordnung.

John Dvorak
quelle
1

Tcl , 37 Bytes

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

Probieren Sie es online! (jetzt laufen alle tests)

Tcl ist einfach. proc s {a b}definiert eine Funktion mit dem Namen, sdie Parameter aund akzeptiert b. regsubErsetzt {}den Wert b, der am Anfang oder Ende von steht, durch eine leere Zeichenfolge a. Die Rückgabe ist implizit.

Michael Plotke
quelle
1

C 96 Bytes

Es ist allgemein bekannt, dass die Manipulation von Saiten in C umständlich ist, da eine Erweiterung des Golfsports eine masochistische Grenze darstellen würde. Klingt in Ordnung für mich.

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

Eines der weniger lesbaren Programme, die ich geschrieben habe. Nimmt zwei Eingaben entgegen ( char**unabhängig davon, wie die Funktion aussieht), eine, die auf die zu dekonkatenierende Zeichenfolge zeigt, und eine, char*die die zu entfernende Zeichenfolge ist. Der Eingabezeiger wird an Ort und Stelle bearbeitet und wird zur Ausgabe (wer sowieso über Speicherverluste spricht).

Anwendungsbeispiel:

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

AWK , 21 32 Bytes

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

Probieren Sie es online!

Die ursprüngliche Einreichung ersetzte naiv den Text innerhalb der ersten Zeichenfolge, nicht nur am Anfang oder Ende.

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

Probieren Sie es online!

Ursprünglich ohne geschweifte Klammern ausprobiert, waren jedoch Tricks erforderlich, um leere Zeilen und / oder keine Übereinstimmungen auszudrucken, wodurch mehr Bytes als in dieser Version hinzugefügt wurden.

Robert Benson
quelle
1

R 20 42 41 Bytes

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

-1 Byte dank MickyT!

Gibt eine anonyme Funktion zurück (die Argumente in der Reihenfolge enthält b,a). Berechnet den Stringunterschied a-b. subist eine einfache Ersetzung, bei der das erste Auftreten des Musters durch die leere Zeichenfolge ersetzt wird ''. Konstruiert den regulären Ausdruck so sprintf, dass er nur am Anfang und am Ende der Zeichenfolge übereinstimmt. Erfordert die pryrInstallation des Pakets.

Verwendet function(a,b)für die TIO-Verknüpfung die ausführlichere Definition für die Funktion für vier weitere Bytes.

Probieren Sie es online!

Giuseppe
quelle
1
Was ist mit dem 'abcde','bcd' -> 'abcde'Fall?
Jonathan Allan
" subist eine einfache Ersetzung, die einfach das erste Vorkommen von bin avertauscht": Wird diese Ersetzung durchgeführt, wenn sich die zweite Zeichenfolge in der Mitte der ersten Zeichenfolge befindet?
TheLethalCoder
Ich habe die Frage falsch verstanden! Hoppla. Danke, dass du das verstanden hast!
Giuseppe
Sie können 1 Byte zurückbekommen mitsprintf('^%s|%s$',b,b)
MickyT
@ MickyT, danke! Fest.
Giuseppe
1

Common Lisp, 121 Bytes

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

Probieren Sie es online!

Das übliche wortreiche Common Lisp!

Ungolfed-Version:

(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
Renzo
quelle
1

Kotlin , 91 Bytes

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

Probieren Sie es online!

Schnecke_
quelle
? {a,b->var c=a.removePrefix(b);if(a==c){c=a.removeSuffix(b)};c}
mazzy
@mazzy zögern Sie nicht, dies als Ihre eigene Antwort zu senden.
snail_
1

Powershell, 34 bis 40 Bytes

+6 Bytes beim Invalid SubtractionHinzufügen von Testfällen

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

Kommentar:

Der Ausdruck regexp ^$t|$t$funktioniert nicht wie erwartet: Er ersetzt beide Übereinstimmungen statt einer (Flag gimmer aktiviert ). Wir sind also gezwungen, die negative Lookahead-Gruppe zu verwenden.

Testskript:

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

Ausgabe:

True: cde
True: ab
True: ab
True: abc
True: abcde
True: acdb
True:
True: abcde
True:
mazzy
quelle
0

QBIC , 57 Bytes

Whegh, das ist ein Durcheinander in 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$
steenbergh
quelle
0

Ich habe die Anweisungen anfangs falsch gelesen. Vielen Dank, Ørjan Johansen, dass Sie auf meinen Fehler hingewiesen haben!

PowerShell , 46 51 Bytes

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

Probieren Sie es online!

Jeff Freeman
quelle
Dies schlägt im Fall 'abcde' 'bcd' fehl.
Ørjan Johansen
Ich sehe erwartete Ergebnisse von diesem Testfall - TIO hier
Jeff Freeman
Es handelt sich um einen aufgelisteten Testfall des OP, und das Ergebnis sollte sein abcde- bcdtritt an keinem Ende des Strings auf.
Ørjan Johansen
Du hast Recht. Ich habe die Anweisungen falsch gelesen. Vielen Dank für den Hinweis!
Jeff Freeman
0

Excel, 129 Bytes

=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)
Wernisch
quelle