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!


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


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.


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


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>


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.

}


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

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"]


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

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 (% ​​/ #)


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


Ich denke, Sie können ein Byte mit retten {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý

@ Zacharý Ja, danke.
Adám



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.



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


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.


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.


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"

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.


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!


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

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!


? {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:

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$


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!


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)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.