字符串减法


37

目的

创建一个函数以反向字符串连接

输入值

两个字符串(字母数字+空格),其中另一个应减去一个。

  • 您可以假设要减去的字符串永远不会大于另一个。

输出量

减法的结果

减法

您应该从另一个字符串的开头或结尾删除一个字符串。如果字符串的开头和结尾都存在,则只能删除一个,然后由您决定删除一个。
如果字符串不是开头或结尾,或者不是完全匹配,则表示这是一个无效的减法,您应该输出原始字符串。

测试用例

有效减法

'abcde','ab' -> 'cde'
'abcde','cde' -> 'ab'
'abab','ab' -> 'ab'
'abcab','ab' -> 'abc' or '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' -> ''

这是,因此以字节为单位的最短代码胜出!


4
为什么第一种情况的结果不是cde?您有效是什么意思?我们需要判断输入的有效性,还是您将不会收到无效的输入?
Leaky Nun

7
该死,'abcde','bcd' -> 'abcde'我为打破我的解决方案而作
约翰·德沃夏克

5
我们是否可以假设字符串是正则表达式安全的(字母数字+空格)?
约翰·德沃夏克

2
我建议'ababcde', 'ab''abcde'作为测试用例。一些幼稚的算法对此失败。

2
@Rod您可能考虑取消挑战“反向字符串串联”?
MD XF

Answers:


19

Java 8,46 45 44 40字节

-1个字节,感谢TheLethalCoder

-1个字节,因为我很笨(感谢Rod!)

-4字节感谢Kevin Cruijssen

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

在线尝试!(包括所有测试用例)

Java答案实际上胜过其他几种实用语言。笑了 (现在胜过JS!)


使用currying保存一个字节a->b->
TheLethalCoder '17

@TheLethalCoder谢谢。
Okx

为什么在在线示例中留下未使用的哈希图?
迈克尔

您可以将更First改为All-2个字节。由于^$总是在String的结尾或开头,因此即使使用replaceAll它也只能替换一次。在这里尝试。PS:我在您的答案中添加了删除的前一个字节数,这通常是在这里对PPCG进行代码高尔夫球编辑后执行的操作。
凯文·克鲁伊森

@KevinCruijssen我知道删除线,猜想我这次忘记了。但是,如果我使用All代替First,这将变为事实:"abab" + "ab" -> ""
Okx

9

JavaScript(ES6),41个字节

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

通过currying语法(即)接受输入f("abab")("ab")


3
现在,为什么我以前eval()从未想到过用于构造RegExes?
毛茸茸的

9

Brachylog(在线试用!),12个字节

~cpĊh.∧Ċtw|w

在线尝试!

从标准输入中减去要减去的字符串,并从命令行中减去要减去的字符串。

说明

~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字节

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

试试吧

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
您不需要new
程序员

@ programmer500,当我看到ETH的版本时,我有点放弃了这个工作!:D现在更新。谢谢。
毛茸茸的

4

Perl 6,21个字节

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

试试吧

展开:

-> $_, $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基本(TI-84 Plus CE),63字节

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

我有一个问题,为什么不使用Str1作为变量?
扎卡里

@Zacharý我想我当时有一些东西在里面。我真的不记得了
pizzapant184 '17

Ans第四行甚至指的是什么?
扎卡里

@Zacharý Ans指的是最后一个评估值,因此在这种情况下,它指的是返回的值inString(,它是字符串中子字符串的索引,如果未出现子Str2字符串Str0则为0。if语句不会修改Ans的值,因此在第四行,索引仍在中Ans
披萨p184 '17

哦,我忘记了如何inString工作。高尔夫不错!
扎卡里

3

Mathematica,162个字节

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

测试输入样式[“ abcde”,“ ab”]


1
不错的解决方案!您可以使用#代替来保存一个字节#1-它们的含义完全相同。另外,StringJoin@t您可以使用来连接空字符串,而不是使用来作弊""<>t,它t也会自动将所有内容连接在一起。您是否看到过Mathematica高尔夫技巧页面
不是一棵树

您还可以做一些其他操作来保存字节(例如,我不认为不需要t={};在开始时进行定义),但是完全使用其他方法可能会更容易-如果您尝试使用StringReplace功能?
不是一棵树

您可以将String数组作为输入,因此您实际上不需要c=Characters;a=c@#;b=c@#2;
JungHwan Min

另外,l@Intersection[a,b]l[a∩b]
JungHwan民


3

66 61 49个字节

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

在线尝试!

少打高尔夫球:

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

使用大小写来测试开始或结束以及数组前缀/后缀(%/#)的减法


1
很好的使用case,但所需时间更长。第二和第三模式可以合并为一个:*)c=${1#$2};;。那么只有2个分支将直接缩短到echo每个分支,而不是使用变量$ccase $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac。或者,您可以继续使用它,但无需casec=${1%$2};[[ $c = $1 ]]&&c=${1#$2};echo $c
manatwork

3

APL(Dyalog)31 30字节

-1感谢Zacharý

这实际上使用了反向(即反向)连接!将原始字符串作为左参数,将减去的值作为右参数。

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

在线尝试!

取消高尔夫:

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

传说:

{} 匿名功能

 当前函数的左参数

 当前函数的正确参数

0::…如果发生任何错误,请执行此操作,否则…

⍣¯1⊢ 逆

,∘⍵在右边 连接

⍵,在左侧 连接


我认为您可以使用保存一个字节{0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}
扎卡里

@Zacharý是的,谢谢。
亚当



2

Haskell,49个字节

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

在线尝试!用法:f"" "abcdef" "ab"。或者,定义(-)=f""并使用like "abcdef" - "ab"

此无正则表达式的解决方案通过以下方式进行工作:将字符串递归拆分为所有前缀和后缀,然后检查要减去的字符串是否与其中之一匹配。



1

C#,88个字节

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

编译为Func<string, Func<string, string>>


1

Ruby(lambda表达式),29个字节

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

是的正则表达式插值!需要进行正则表达式安全的子换行,但是根据挑战就可以了。


1

Tcl,37个字节

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

在线尝试!(现在正在运行所有测试)

Tcl很简单。proc s {a b}定义一个名为的函数s,该函数带有参数abregsubreplaces {}是一个空字符串,用于b当它位于的开始或结尾时的值a。返回是隐式的。


1

C,96字节

众所周知,C语言中的字符串操作非常繁琐,因为扩展打高尔夫球会成为自虐狂。对我来说听起来不错。

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

我编写的可读性较差的程序之一。接受两个输入(尽管函数看起来如何),一个char**指向要取消连接的字符串的指针,另一个char*是要删除的字符串。输入指针在适当位置被编辑并成为输出(无论如何,它们都涉及内存泄漏)。

用法示例:

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

1

AWK21 32字节

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

在线尝试!

原始提交内容天真地替换了第一个字符串中的文本,而不仅仅是在开头或结尾。

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

在线尝试!

最初尝试不使用花括号,但是它需要技巧来打印出空行和/或不匹配项,最终增加了比此版本更多的字节。


1

R,20 42 41字节

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

-1个字节感谢MickyT!

返回一个匿名函数(其参数顺序为b,a)。计算字符串差异a-bsub是一个简单的替换,它将模式的第一次出现与(在这种情况下)空字符串交换''。构造sprintf仅与字符串的开头和结尾相匹配的regex 。需要pryr安装软件包。

在TIO链接上,function(a,b)对函数使用更详细的定义以获得另外四个字节。

在线尝试!


1
那怎么'abcde','bcd' -> 'abcde'
乔纳森·艾伦

sub是一个简单替换,它简单地交换bin中的第一次出现a:如果第二个字符串在第一个字符串的中间,那么是否会进行交换?
TheLethalCoder

我看错了问题!哎呀。感谢您抓住这一点!
朱塞佩

您可以用sprintf('^%s|%s$',b,b)
MickyT

@MickyT,谢谢!固定。
朱塞佩

1

Common Lisp,121个字节

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

在线尝试!

通常罗word的普通Lisp!

非高尔夫版本:

(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

Powershell,34个 40字节

Invalid Subtraction添加测试用例时+6字节

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

评论:

regexp表达式^$t|$t$不能按预期工作:替换两个匹配项,而是替换一个(标志g始终处于打开状态)。因此,我们不得不使用否定超前组。

测试脚本:

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

输出:

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

0

QBIC,57字节

哎呀,这在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

我最初误读了说明。谢谢ØrjanJohansen指出我的错误!

PowerShell46 51字节

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

在线尝试!


这在'abcde''bcd'情况下失败。
与Orjan约翰森

我看到了该测试用例的预期结果- 这里的
Jeff Freeman

这是OP列出的测试用例,结果应该是abcde- bcd不在字符串的两端出现。
与Orjan约翰森

你是对的。我误读了说明。感谢您指出!
杰夫·弗里曼

0

Excel,129个字节

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.