切换字符串


15

挑战涉及简单地在另一个字符串中切换一个字符串。

说明

如果切换字符串主字符串的子字符串,则从主字符串中删除切换字符串的所有实例; 否则,将切换字符串附加在main string的末尾。

规则

  • 所有字符串均由可打印的ASCII字符组成
  • 该函数应带有两个参数:主字符串切换字符串
  • 主串可以是空的。
  • 拨动弦不能为空。
  • 结果应该是一个字符串,可以为空。
  • 最短的答案将获胜。

例子

function toggle(main_string, toggle_string){ ... }

toggle('this string has 6 words ', 'now') 
=> 'this string has 6 words now'

toggle('this string has 5 words now', ' now') 
=> 'this string has 5 words'

测试案例

'','a'          => 'a'
'a','a'         => ''

'b','a'         => 'ba'
'ab','a'        => 'b'

'aba','a'       => 'b'
'ababa', 'aba'  => 'ba'

2
@KennyLau三个小时都在沙盒中。建议为2天。
摩根·塔普

9
建议实际上是72小时。主页具有比“沙箱”更高的可见性,因此在此保证了更多评论。就是说,这不是一个挑战,只是有一些粗糙的地方。
AdmBorkBork,2016年

2
因此,您替换了所有不重叠的实例吗?
Suever

1
@Jakube是的,我应该限制为我认为的字母和数字。
nobe4

1
不,我认为允许使用非字母数字:这样更具挑战性。
msh210 '16

Answers:


5

果冻,7 个字节

œṣȮ⁸e⁹ẋ

在线尝试!

怎么运行的

œṣȮ⁸e⁹ẋ  Main link. Arguments: s (string), t (toggle string)

œṣ       Split s at occurrences of t.
  Ȯ      Print the result.
   ⁸e    Check if s occurs in the split s. Yields 1 (true) or 0 (false).
     ⁹ẋ  Repeat t that many times.

11

爪哇8,80 70 65 34字节

t->m->m==(m=m.replace(t,""))?m+t:m

可能是我到目前为止最短的Java'codegolf'。.xD
在注释中提供了一些帮助。

说明:

在线尝试。

t->m->                     // Method with two String parameters and String return-type
                           // (NOTE: Takes the toggle `t` and main `m` in reversed order)
  m==(m=m.replace(t,""))?  //  If `m` equals `m` with all `t`-substrings removed:
                           //  (And set `m` to `m` with all `t`-substrings removed)
   m+t                     //   Output this new `m` concatted with `t`
  :                        //  Else:
   m                       //   Output just this new `m`

1
通过将更if改为三进制,您应该能够节省很多。如果没有别的,它将摆脱“ extra” return
Geobits '16

@Geobits Ah,当然..我非常热心,以至于单个方法的字节数很低(就Java的“ codegolfing”而言),我忘记了ifs和return最明显的codegolfing之一。谢谢,编辑。
凯文·克鲁伊森

1
您可以通过使用lambda而不是常规函数来节省更多字节。
丹克

return m=m.replace(t,"")?m+t:m;
Leaky Nun

2
m==(m=m.replace...
Leaky Nun

8

MATL,11个字节

yyXf?''YX}h

在线尝试!

所有测试用例

说明

            % Implicitly grab the main string
            % Implicitly grab the toggle string
y           % Copy the main string
y           % Copy the toggle string
Xf          % Check to see if the toggle string is present in the main string
?           % If so
    ''YX    % Replace with an empty string
}           % else
    h       % Horizontally concatenate the two strings
            % Implicit end of if...else
            % Implicitly display the result

6

Python 3,38个字节

lambda s,t:(s+t,s.replace(t,""))[t in s]

4

JavaScript(ES6),39 37字节

(s,t,u=s.split(t).join``)=>u==s?s+t:u

3

Pyke,14个字节

DX{iIXRk:)i!IJ

在这里尝试!

鉴于派克(Pyke)没有 else结构,我认为这是相当合理的分数

说明:

D              -    Duplicate input
 X             -   a,b = ^
  {            -  a in b
   i           - i = ^
    I          - if i:
     XRk:      -  a = b.replace(a,"")
         i!I   - if not i:
            J  -  a = "".join(input)
               - print a

3

CJam,9岁

q~:B/2Be]

在线尝试。感谢jimmy23013砍掉1个字节:)

说明:

q~     read and evaluate the input (given as 2 quoted strings)
:B     store the toggle string in B
/      split the main string by the toggle string
2Be]   pad the array of pieces to the right with B, up to length 2 (if shorter)

1
9个字节:q~:B/2Be]
jimmy23013 '16

2

Javascript(ECMAScript 6):47个位元组

(a,b)=>(c=a.replace(RegExp(b,'g'),''))!=a?c:a+b

5
如果切换字符串包含特殊字符,则可能会失败。例如,("a", ".")返回""而不是"a."
丹尼斯

2

视网膜38 31字节

字节数假定为ISO 8859-1编码。

(.+)(?=.*¶\1$)
·
1>`·|¶.+

T`·¶

尾随换行很重要。输入格式是两个用换行符分隔的字符串。

在线尝试!第一行允许一次运行多个测试用例(对于测试套件,用于;分隔字符串和换行符以分隔测试用例;第一行负责转换)。

说明

(.+)(?=.*¶\1$)
·

在第一步中,我们用替换主字符串中所有出现的切换字符串·。我们需要插入这些标记,以便以后可以确定是否发生任何替换。

1>`·|¶.+

这是另一个替代,它删除了·标记或第二行(包括分隔的换行符)。但是,这1>是一个限制,这意味着仅考虑第一个之后的匹配项。因此,如果切换字符串未出现在主字符串中,则不会插入any ·,因此第二行将是第一个匹配项,不会被删除。否则,我们将删除第二行以及第一个标记以外的所有标记。

T`·¶

尽管这使用了音译阶段,但它也仅用于删除字符。特别是,我们同时移动了·换行符。我们需要第一个,如果有匹配项(因为第·一个阶段将被上一阶段遗忘),而我们需要第二个,如果没有匹配项(将两行连接在一起,从而将切换字符串附加到主字符串)。


2

Python(3.4):55 54 47 44字节

lambda m,t:m.replace(t,'')if t in m else m+t

测试:

toggle=lambda m,t:m.replace(t,'')if t in m else m+t
print('', 'a', toggle('','a'))
print('a', 'a', toggle('a','a'))
print('b', 'a', toggle('b','a'))
print('ab', 'a', toggle('ab','a'))
print('aba', 'a', toggle('aba','a'))
print('ababa', 'aba', toggle('ababa','aba'))

测试输出

 a a
a a
b a ba
ab a b
aba a b
ababa aba ba

使用def会更长,因为您必须使用return语句,如果可以不返回就可以节省2个字节。 由于不需要显式声明函数(对不起,我不知道),因此节省了7个字节。


好答案!对于我们的规则,您不需要该函数的名称。因此,您可以删除toggle=
Rɪᴋᴇʀ

我只是意识到,如果我不命名函数,我的测试将无法正常工作,但是随着toggle=Tests的工作
莱万特,2016年

是的,toggle需要对其进行测试。但是,你只需要lambda m,t:上。
Rɪᴋᴇʀ

如果我没有记错的话,可以更改m+''+tm+t保存3个字节。
Sherlock16年

没错,我首先m+' '+t在它们之间输入一个空格,但在再次阅读说明之后,我删除了空白,但没有删除''和+
levanth,2016年

2

C#,63

string F(string s,string t)=>s.Contains(t)?s.Replace(t,""):s+t;

比Java更好:)

测试代码:

public static void Main()
{
    Console.WriteLine(F("", "a"));
    Console.WriteLine(F("a", "a"));
    Console.WriteLine(F("b", "a"));
    Console.WriteLine(F("ab", "a"));
    Console.WriteLine(F("aba", "a"));
    Console.WriteLine(F("ababa", "aba"));
    Console.ReadLine();
}

输出:

a

ba
b
b
ba


2

Jolf,12个字节

?=iγρiIE+iIγ

或者,如果必须包含对正则表达式敏感的字符:

?=iγρiLeIE+iIγ

在这里尝试!

说明

?=iγρiIE+iIγ    if(i === (γ = i.replace(I, E))) alert(i + I); else alert(γ);
  i                i
 =                   ===
    ρ                          .replace( ,  )
     iI                       i         I 
       E                                   E
   γ                     (γ =                )
?               if(                           )
        +iI                                     alert(i + I);
                                                              else
           γ                                                       alert(γ);

2

JavaScript(ES6),37个字节

(m,t)=>(w=m.split(t).join``)==m?m+t:w

利用split和join的优势,比@ nobe4的答案略短


2

球拍,70个字节

非常简单。

(λ(s t)((if(string-contains? s t)string-replace string-append)s t""))

2

Scala,72 70字节

def x(m:String,s:String)={val r=m.replaceAll(s,"");if(r==m)m+s else r}

在线口译:www.tryscala.com


1
欢迎来到编程难题和代码高尔夫球!我不了解Scala,但我认为您可以删除周围的空格if(r==m)
丹尼斯

是的,您说对了
阿维斯

1

Oracle SQL 11.2,66字节

SELECT DECODE(:1,s,s||:2,s)FROM(SELECT REPLACE(:1,:2)s FROM DUAL);

1

Perl,37个 30字节

{$_=shift;s/\Q@_//g?$_:"$_@_"}

由于使用\Q... 引号,因此无法评估切换字符串内的正则表达式\E

sub F\E根据msh210 的注释将其删除。

由于凝结,它并非完全没有副作用$_。使用局部变量将花费另外六个字节:

{my$a=shift;$a=~s/\Q@_//g?$a:"$a@_"}

另一方面,对于切换的输入参数,可以使用pop而不是shift(28个字节)来保存两个字节:

{$_=pop;s/\Q@_//g?$_:"$_@_"}

测试文件:

#!/usr/bin/env perl

sub F{$_=shift;s/\Q@_//g?$_:"$_@_"}

sub test ($$$) {
  my ($m, $t, $r) = @_;
  my $result = F($m, $t);
  print "F('$m', '$t') -> '$result' ",
    ($result eq $r ? '=OK=' : '<ERROR>'), " '$r'\n";
}
test '', 'a', 'a';
test 'a', 'a', '';
test 'b', 'a', 'ba';
test 'ab', 'a', 'b';
test 'aba', 'a', 'b';
test 'ababa', 'aba', 'ba';
test 'ababa', 'a*', 'ababaa*';
test 'foobar', '.', 'foobar.';
__END__

测试结果:

F('', 'a') -> 'a' =OK= 'a'
F('a', 'a') -> '' =OK= ''
F('b', 'a') -> 'ba' =OK= 'ba'
F('ab', 'a') -> 'b' =OK= 'b'
F('aba', 'a') -> 'b' =OK= 'b'
F('ababa', 'aba') -> 'ba' =OK= 'ba'
F('ababa', 'a*') -> 'ababaa*' =OK= 'ababaa*'
F('foobar', '.') -> 'foobar.' =OK= 'foobar.'

perlsub说:“签名是子例程主体的一部分。通常,子例程主体只是一段支撑代码。” 因此,您可以省略sub F字节数。同样,您应该能够使用pop而不是shift(通过反转输入顺序natch)节省两个字节。(未经测试。)最后,您应该能够省略\E,节省两个字节。(也未经测试。)
msh210 '16

@ msh210谢谢,您的提示节省了七个字节。我看不到,该如何pop代替shift可以有所帮助,因为$_应该成为要避免的第一个论点$_[1]=~s/.../。输入自变量的顺序由问题AFAIK固定。
Heiko Oberdiek '16

输入参数的顺序不是由问题afaict确定的。
msh210 '16

1

C#(58字节)

string F(string s,string t)=>s==(s=s.Replace(t,""))?s+t:s;

它使用内联分配来剃除一些字节


您好,欢迎来到PPCG!很棒的第一篇文章!我不使用C#多,但不能这样做var s,tvar s,var t代替string
NoOneIsHere

谢谢!可悲的是var只能在编译时知道类型的地方使用,因此不能在方法签名中使用。您可以使用dynamic,但要长1个字符string
Blue0500 2016年

var F(string s, string t呢 可以推断...
NoOneIsHere16年

1

bash + sed,28个字节

sed "s/$2//g;t;s/$/$2/"<<<$1

该脚本位于一个toggle-string.bash文件中,我们称之为 bash toggle-string.bash mainstring togglestring

s/$2//g 从主字符串中删除切换字符串

t 如果先前的替换成功,则跳转到结尾(即,主字符串包含切换字符串)

/$/$2/ 在结尾添加切换字符串($如果我们没有跳到结尾,则)

bash是herestring必需的


如果切换字符串包含特殊字符,则此功能将无效。
丹尼斯


0

PowerShell v2 +,47个字节

param($a,$b)(($c=$a-replace$b),"$a$b")[$c-eq$a]

接受输入$a,$b,然后使用伪三元(... , ...)[...]语句执行if / else。首先评估内部零件,以形成两个元素的数组。d的$a所有出现都为0 $b -replace,而没有任何结果,将其存储到中$c。第1只是一个字符串连接$a$b

如果$c-eqUAL到$a,这个含义$b没有被发现,这是布尔$true1,因此被选择的阵列(级联)的第一元件。否则,它是Boolean $false,所以我们输出$c第0个元素。

请注意,这-replace是贪婪的,因此它将首先从左开始替换,这意味着ababa / aba测试用例将正确返回ba


0

Java 8,65字节

BinaryOperator<String>l=(m,t)->m.contains(t)?m.replace(t,""):m+t;

用lambda编写的与Java 7解决方案相同的逻辑。

在这里尝试



0

Mathematica,45个字节

If[StringContainsQ@##,StringDelete@##,#<>#2]&

匿名函数,接受主字符串和切换字符串(按此顺序)并返回结果。说明:

                                            &  Anonymous function returning...

If[StringContainsQ@##,               ,     ]    if its first argument contains
                                                its second argument, then...
                      StringDelete@##            its first argument with its
                                                 second argument removed, else...
                                      #<>#2      its second argument appended to
                                                 its first argument.

0

TSQL,143个 129个 121字节

DECLARE @1 VARCHAR(10)='',@2 VARCHAR(10)='a'SELECT CASE WHEN @1 LIKE'%'+@2+'%'THEN REPLACE(@1,@2,'')ELSE CONCAT(@1,@2)END

可读性:

   DECLARE @1 VARCHAR(10) = ''
    , @2 VARCHAR(10) = 'a'

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2)
            END

Live Demo

114个字节,仅输入1个字符

DECLARE @1 CHAR(1) = 'a'
    , @2 CHAR(1) = '.'

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2) END

您好,欢迎来到PPCG!好答案!
NoOneIsHere

0

TSQL(Sqlserver 2012),49字节

DECLARE @ VARCHAR(10) = 'hello',@x VARCHAR(10) = 'o'

PRINT IIF(@ LIKE'%'+@x+'%',REPLACE(@,@x,''),@+@x)

在线尝试!


0

Ruby,35 37 28字节

->m,t{m[t]?m.gsub(t,''):m+t}

万岁字符串插值!它甚至可以在正则表达式中使用。其余的很简单:如果中的字符串t与匹配m,则替换t'',否则返回m+t

编辑:修复了一个错误。

编辑:我采用了Kevin Lau的建议,但看来我已经达到了与Luis Masuelli的答案中使用的算法相同的算法。


如果切换字符串包含特殊字符,则可能会失败。例如,("a", ".")返回"a"而不是"a."
丹尼斯

m[t]m.include?(t)字符串短得多,并且仍在检查是否包含在字符串中。
价值墨水

0

k(23个字节)

{$[#x ss y;,/y\:x;x,y]}

例子:

k){$[#x ss y;,/y\:x;x,y]}["aba";"a"]
,"b"
k){$[#x ss y;,/y\:x;x,y]}["this string has 6 words ";"now"]
"this string has 6 words now"
k){$[#x ss y;,/y\:x;x,y]}["this string has 5 words now";"now"]
"this string has 5 words "
k){$[#x ss y;,/y\:x;x,y]}["ababa";"ba"]
,"a"
k){$[#x ss y;,/y\:x;x,y]}["";"a"]
,"a"

0

Kotlin,61字节

{m:String,t:String->var n=m.replace(t,"");if(m==n)m+t else n}

如果赋值是Kotlin中的一个表达式,并且参数是可变的,并且有一个三元条件运算符,那么会更短一些,可惜不是这样的:(

在线尝试!

松散

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
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.