สลับสตริง


15

ความท้าทายเกี่ยวข้องกับการสลับสตริงภายในสายอื่น

คำอธิบาย

ถ้าสตริงสลับเป็นย่อยของสตริงหลักเอาทุกกรณีของสตริงสลับจากสตริงหลัก ; มิฉะนั้นผนวกสตริงสลับในตอนท้ายของสตริงหลัก

กฎระเบียบ

  • สตริงทั้งหมดประกอบด้วยอักขระ 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 มันอยู่ในกล่องทรายเป็นเวลา 3 ชั่วโมง คำแนะนำคือ 2 วัน
Morgan Thrapp

9
ข้อเสนอแนะที่เป็นจริง72 ชั่วโมง หน้าหลักมีการเปิดเผยมากกว่า Sandbox ดังนั้นรับประกันความคิดเห็นเพิ่มเติมที่นี่ ที่กล่าวว่านี่ไม่ใช่ความท้าทายที่ไม่ดีเพียงแค่มีขอบที่ขรุขระเล็กน้อย
AdmBorkBork

2
ดังนั้นคุณจะแทนที่อินสแตนซ์ที่ไม่ทับซ้อนกันทั้งหมดหรือไม่
Suever

1
@ Jakube ใช่ฉันควร จำกัด สิ่งนี้ไว้ที่ตัวอักษรและตัวเลขที่ฉันคิด
nobe4

1
ไม่ฉันคิดว่าอนุญาตตัวเลขที่ไม่ใช่ตัวเลข: มันท้าทายมากกว่านี้
msh210

คำตอบ:



11

Java 8, 80 70 65 34 ไบต์

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

อาจจะเป็น '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เป็นไตรภาค ถ้าไม่มีอะไรก็จะได้รับการกำจัดของ return"พิเศษ"
Geobits

@Geobits อาแน่นอน .. ฉันกระตือรือร้นมากที่วิธีการเดียวมีจำนวนไบต์ 'ต่ำ' (ในแง่ของจาวา 'codegolfing') ที่ฉันลืม codegolfing ที่เห็นได้ชัดที่สุดสำหรับ ifs และส่งคืน .. >> ขอขอบคุณแก้ไข
Kevin Cruijssen

1
คุณสามารถบันทึกได้อีกสองสามไบต์โดยใช้แลมบ์ดาแทนฟังก์ชั่นปกติ
Denker

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

2
m==(m=m.replace...
Leun 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



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

2

Javascript (ECMAScript 6): 47 ไบต์

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

5
สิ่งนี้อาจล้มเหลวหากสตริงสลับมีอักขระพิเศษ ตัวอย่างเช่น("a", ".")ผลตอบแทนแทน"" "a."
Dennis

2

เรติน่า , 38 31 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

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

T`·¶

ตัวป้อนบรรทัดต่อท้ายมีความสำคัญ รูปแบบอินพุตเป็นทั้งสตริงที่คั่นด้วย linefeed

ลองออนไลน์!บรรทัดแรกอนุญาตให้เรียกใช้หลายกรณีทดสอบในคราวเดียว (สำหรับชุดทดสอบให้ใช้;เพื่อแยกสตริงและ linefeeds เพื่อแยกกรณีทดสอบบรรทัดแรกดูแลการแปลง)

คำอธิบาย

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

·ในขั้นตอนแรกนี้เราแทนที่เกิดขึ้นทั้งหมดของสตริงสลับในสตริงหลัก เราจำเป็นต้องใส่เครื่องหมายเหล่านี้เพื่อให้เราสามารถตรวจสอบภายหลังว่ามีการทดแทนเกิดขึ้น

1>`·|¶.+

นี่คือการทดแทนอื่นซึ่งลบ·เครื่องหมายหรือบรรทัดที่สอง (รวมถึงการแยก linefeed) อย่างไรก็ตาม1>จำกัด นั้นหมายถึงว่าจะมีการพิจารณาการจับคู่หลังจากครั้งแรกเท่านั้น ดังนั้นหากสตริงสลับไม่ได้เกิดขึ้นในสตริงหลักเราจะไม่แทรกใด ๆ·ดังนั้นบรรทัดที่สองจะเป็นการจับคู่ครั้งแรกและจะไม่ถูกลบออก มิฉะนั้นเราจะลบบรรทัดที่สองพร้อมด้วยทั้งหมดยกเว้นเครื่องหมายแรก

T`·¶

ในขณะที่ใช้ขั้นตอนการทับศัพท์มันก็ใช้สำหรับการลบตัวอักษร โดยเฉพาะอย่างยิ่งเราย้ายทั้งสอง·และ linefeeds เราต้องการคนแรกในกรณีที่มีการแข่งขัน (เพราะจากนั้นเป็นครั้งแรก·จะถูกทิ้งไว้ข้างหลังโดยขั้นตอนก่อนหน้า) และเราต้องการที่สองในกรณีที่ไม่มีการแข่งขัน (เพื่อเข้าร่วมสองบรรทัดด้วยกันและด้วยเหตุนี้ ผนวกสายอักขระสลับกับสายหลัก)


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 Bytes ถูกบันทึกไว้


คำตอบที่ดี! สำหรับกฎของเราคุณไม่ต้องการชื่อฟังก์ชั่น toggle=ดังนั้นคุณสามารถลบ
Rɪᴋᴇʀ

ฉันเพิ่งรู้ว่าการทดสอบของฉันจะไม่ทำงานถ้าฉันไม่ได้ตั้งชื่อฟังก์ชั่น แต่ด้วยtoggle=การทดสอบการทำงาน
levanth

ใช่toggleจำเป็นต้องมีการทดสอบ แต่คุณต้องนับจากlambda m,t:เมื่อ
Rɪᴋᴇʀ

คุณสามารถเปลี่ยนm+''+tเป็นm+tบันทึก 3 ไบต์ถ้าฉันไม่เข้าใจผิด
Sherlock9

คุณถูกต้องฉันเริ่มต้นด้วยm+' '+tการป้อนช่องว่างระหว่างพวกเขา แต่หลังจากอ่านคำอธิบายอีกครั้งฉันลบช่องว่าง แต่ไม่ใช่ '' และ +
levanth

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

Pyth, 13 11 10 ไบต์

?/Qz:Qzk+z

ชุดทดสอบ

รูปแบบอินพุต: สตริงแรกในเครื่องหมายคำพูดสตริงที่สองที่ไม่มีเครื่องหมายคำพูด

นี่คือ 10 ไบต์ด้วย:

?tJcQzsJ+z

ชุดทดสอบ

นี่คือ 11 ไบต์:

pscQz*!}zQz

ชุดทดสอบ

โซลูชัน 13 ไบต์ก่อนหน้า:

?:IQzk+Qz:Qzk

ชุดทดสอบ


1
11 ไบต์ด้วย:?}zQ:Qzk+Qz
บลู

2

Jolf 12 ไบต์

?=iγρiIE+iIγ

หรือถ้าเราต้องรวมตัวอักษรที่ไวต่อ regex:

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

สั้นกว่าคำตอบของ @ nobe4 เล็กน้อยโดยใช้ประโยชน์จากการแยกและเข้าร่วม


2

แร็กเก็ต, 70 ไบต์

ตรงไปตรงมาสวย

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

2

สกาลา72 70 ไบต์

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

ล่ามออนไลน์: www.tryscala.com


1
ยินดีต้อนรับสู่ Programming Puzzles & Code Golf! ฉันไม่รู้สกาล่า แต่ฉันคิดว่าคุณสามารถลบช่องว่างif(r==m)ออกได้
Dennis

ใช่คุณพูดถูก
Avis


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

@ msh210 ขอบคุณเคล็ดลับของคุณบันทึกเจ็ดไบต์ ฉันไม่เห็นว่าอย่างไรpopแทนshiftความช่วยเหลือสามารถเพราะควรจะอาร์กิวเมนต์แรกที่ควรหลีกเลี่ยง$_ $_[1]=~s/.../ลำดับของอาร์กิวเมนต์ที่ป้อนเข้าจะถูกแก้ไขโดยคำถาม AFAIK
Heiko Oberdiek

ลำดับของอาร์กิวเมนต์ที่ป้อนเข้าไม่ได้รับการแก้ไขโดยคำถาม afaict
msh210

1

C # (58 ไบต์)

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

มันใช้การกำหนดแบบอินไลน์ในการโกนไม่กี่ไบต์


สวัสดีและยินดีต้อนรับสู่ PPCG! โพสต์แรกสุดยอด! ฉันไม่ได้ใช้ C # มาก แต่คุณไม่สามารถทำvar s,tหรือvar s,var tแทนได้string?
NoOneIsHere ที่

ขอบคุณ! น่าเศร้าvarสามารถใช้ได้เฉพาะในสถานที่ที่เป็นที่รู้จักกันในเวลารวบรวมดังนั้นจึงไม่สามารถใช้ในลายเซ็นวิธี คุณสามารถใช้งานdynamicได้ แต่จะยาวกว่า 1 ตัวอักษรstring
Blue0500

เกี่ยวกับvar F(string s, string tอะไร สามารถอนุมานได้ว่า ...
ใครอยู่ที่นี่

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/ เพิ่มสตริงสลับที่ท้าย ($ ) หากเราไม่ได้ข้ามไปยังจุดสิ้นสุด

ทุบตีเป็นสิ่งจำเป็นสำหรับ herestring


สิ่งนี้จะไม่ทำงานหากสตริงสลับมีอักขระพิเศษ
เดนนิส


0

PowerShell v2 +, 47 ไบต์

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

รับอินพุต$a,$bจากนั้นใช้(... , ...)[...]คำสั่งpseudo-ternary เพื่อดำเนินการ if / else ชิ้นส่วนภายในจะถูกประเมินก่อนเพื่อสร้างอาร์เรย์ของสององค์ประกอบ 0th คือ$aสิ่งที่เกิดขึ้นทั้งหมดของ$b -replaced โดยไม่มีอะไรซึ่งถูกเก็บไว้ใน$cมีอะไรซึ่งเป็นที่เก็บไว้ใน ที่ 1 เป็นเพียงการต่อสายของ$a$bและ

ถ้า$cเป็น-equal ถึง$aหมายถึง$bไม่พบนั่นคือบูลีน$trueหรือ1ดังนั้นองค์ประกอบที่ 1 ของอาร์เรย์ (การต่อข้อมูล) จะถูกเลือก อื่นมันเป็นบูลีน$falseดังนั้นเราจึงเอาท์พุท$cองค์ประกอบที่ 0

ทราบว่า-replaceเป็นโลภจึงจะเปลี่ยนจากซ้ายคนแรกหมายถึงกรณีทดสอบอย่างถูกต้องจะกลับมาababa / ababa



0

Ruby, 33 ไบต์ 27 ไบต์ (28 ถ้าใช้การลบย่อยทั่วโลก) 28 ไบต์แน่นอน

->u,v{u[v]?u.gsub(v,''):u+v}

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

Ruby, 35 37 28 ไบต์

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

ไชโยสำหรับการแก้ไขสตริง! มันยังทำงานได้ใน regexes ส่วนที่เหลือเป็นเรื่องง่าย: ถ้าสตริงในtแมตช์ที่จะmแทนที่tด้วยผลตอบแทนอื่น''m+t

แก้ไข:แก้ไขข้อผิดพลาด

แก้ไข:ฉันใช้ข้อเสนอแนะของเควิน Lau แต่ก็ปรากฏว่าผมได้มาถึงขั้นตอนวิธีการเดียวกับที่ใช้ในคำตอบของหลุยส์ Masuelli ของ


สิ่งนี้อาจล้มเหลวหากสตริงสลับมีอักขระพิเศษ ตัวอย่างเช่น("a", ".")ผลตอบแทนแทน"a" "a."
Dennis

m[t]สั้นกว่ามากm.include?(t)และยังคงตรวจสอบการรวมอยู่ในสตริง
Ink Value

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 และพารามิเตอร์ไม่แน่นอนและมีผู้ประกอบการเงื่อนไขแบบไตรภาคน่าเศร้าที่นี่ไม่ใช่กรณี :(

ลองออนไลน์!

UnGolfed

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.