Chuyển đổi một chuỗi


15

Thách thức liên quan đến việc đơn giản là chuyển một chuỗi trong một chuỗi khác.

Giải trình

Nếu chuỗi chuyển đổi là một chuỗi con của chuỗi chính , hãy xóa tất cả các phiên bản của chuỗi chuyển đổi khỏi chuỗi chính ; mặt khác, nối thêm chuỗi chuyển đổi ở cuối chuỗi chính .

Quy tắc

  • Tất cả các chuỗi bao gồm các ký tự ASCII có thể in
  • Hàm nên có hai tham số: chuỗi chínhchuỗi chuyển đổi .
  • Chuỗi chính có thể trống.
  • Chuỗi chuyển đổi không thể để trống.
  • Kết quả phải là một chuỗi, có thể để trống.
  • Câu trả lời ngắn nhất sẽ thắng.

Ví dụ

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'

Các trường hợp xét nghiệm

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

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

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

2
@KennyLau Nó đã ở trong hộp cát trong cả 3 giờ. Khuyến nghị là 2 ngày.
Morgan Thrapp

9
Các khuyến nghị thực sự là 72 giờ . Trang chính có khả năng hiển thị nhiều hơn so với Sandbox, vì vậy nhiều bình luận được đảm bảo ở đây. Điều đó nói rằng, đây không phải là một thách thức xấu , chỉ có một vài cạnh khó khăn.
admBorkBork

2
Vì vậy, bạn thay thế tất cả các trường hợp không chồng chéo ?
Suever

1
@Jakube Vâng, tôi nên giới hạn điều này trong các chữ cái và số tôi nghĩ.
nobe4

1
Không, tôi nghĩ cho phép những người không phải dân tộc học: nó khó khăn hơn theo cách đó.
msh210

Câu trả lời:


5

Thạch , 7 byte

œṣȮ⁸e⁹ẋ

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

œṣȮ⁸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

Java 8, 80 70 65 34 byte

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

Có lẽ là Java 'codegolf' ngắn nhất của tôi cho đến nay .. xD
với một số trợ giúp từ các bình luận ..;)

Giải trình:

Hãy thử trực tuyến.

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
Bạn sẽ có thể tiết kiệm khá nhiều bằng cách thay đổi ifthành một con chim nhạn. Nếu không có gì khác, nó sẽ thoát khỏi "thêm" return.
Geobits

@Geobits Ah, tất nhiên .. Tôi đã rất nhiệt tình khi một phương thức duy nhất có số byte 'thấp' (theo java 'codegolfing') đến nỗi tôi đã quên một trong những cách mã hóa rõ ràng nhất cho if và trả về ..>.> Cảm ơn, chỉnh sửa.
Kevin Cruijssen

1
Bạn có thể lưu thêm một vài byte bằng cách sử dụng lambda thay vì hàm thông thường.
Denker

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

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

8

MATL, 11 byte

yyXf?''YX}h

Hãy thử trực tuyến!

Tất cả các trường hợp thử nghiệm

Giải trình

            % 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


4

JavaScript (ES6), 39 37 byte

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

3

Pyke, 14 byte

DX{iIXRk:)i!IJ

Hãy thử nó ở đây!

Cho rằng Pyke không có else cấu trúc, tôi nghĩ rằng đây là điểm số khá hợp lý

Giải trình:

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]

Hãy thử trực tuyến. Cảm ơn jimmy23013 vì đã cắt 1 byte :)

Giải trình:

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 byte : q~:B/2Be].
jimmy23013

2

Javascript (ECMAScript 6): 47 byte

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

5
Điều này có thể thất bại nếu chuỗi chuyển đổi có chứa các ký tự đặc biệt. Ví dụ, ("a", ".")trả về ""thay vì "a.".
Dennis

2

Võng mạc , 38 31 byte

Số lượng byte giả định mã hóa ISO 8859-1.

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

T`·¶

Các linefeed trailing là đáng kể. Định dạng đầu vào là cả hai chuỗi được phân tách bằng một nguồn cấp.

Hãy thử trực tuyến! Dòng đầu tiên cho phép chạy một số trường hợp thử nghiệm cùng một lúc (đối với bộ thử nghiệm, sử dụng ;để tách các chuỗi và nguồn cấp dữ liệu để tách các trường hợp thử nghiệm; dòng đầu tiên đảm nhiệm việc chuyển đổi).

Giải trình

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

Trong bước đầu tiên này, chúng tôi thay thế tất cả các lần xuất hiện của chuỗi chuyển đổi trong chuỗi chính bằng ·. Chúng ta cần chèn các điểm đánh dấu này để có thể xác định sau đó nếu có bất kỳ sự thay thế nào xảy ra.

1>`·|¶.+

Đây là một sự thay thế khác loại bỏ một ·điểm đánh dấu hoặc dòng thứ hai (bao gồm cả dòng cấp tách biệt). Tuy nhiên, 1>giới hạn này có nghĩa là chỉ khớp sau lần đầu tiên được xem xét. Do đó, nếu chuỗi chuyển đổi không xảy ra trong chuỗi chính, chúng tôi sẽ không chèn bất kỳ ·, vì vậy dòng thứ hai sẽ là kết quả khớp đầu tiên và sẽ không bị xóa. Mặt khác, chúng tôi loại bỏ dòng thứ hai cùng với tất cả trừ điểm đánh dấu đầu tiên.

T`·¶

Trong khi điều này sử dụng một giai đoạn chuyển ngữ, nó cũng được sử dụng đơn giản để loại bỏ các ký tự. Đặc biệt, chúng tôi di chuyển cả hai ·và nguồn cấp dữ liệu. Chúng tôi cần cái đầu tiên, trong trường hợp có một trận đấu (vì sau đó trận đầu tiên ·sẽ bị bỏ lại phía sau bởi giai đoạn trước) và chúng tôi cần cái thứ hai trong trường hợp không có trận đấu (để nối hai dòng với nhau nối chuỗi chuyển đổi vào chuỗi chính).


2

Python (3,4): 55 54 47 44 byte

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

Kiểm tra:

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

Đầu ra thử nghiệm

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

Sử dụng def sẽ lâu hơn vì bạn phải sử dụng câu lệnh return, nếu có thể mà không trả về thì sẽ tiết kiệm được 2 Byte Vì không cần phải khai báo rõ ràng về chức năng (xin lỗi tôi không biết rằng) 7 byte đã được lưu.


Câu trả lời tốt đẹp! Đối với quy tắc của chúng tôi, bạn không cần tên cho hàm. Vì vậy, bạn có thể loại bỏ toggle=.
Rɪᴋᴇʀ

Tôi mới nhận ra, Thử nghiệm của tôi sẽ không hoạt động nếu tôi không đặt tên cho chức năng, nhưng với toggle=thử nghiệm hoạt động
levanth

vâng, togglecần thiết để kiểm tra nó Nhưng bạn chỉ cần tính từ lambda m,t:.
Rɪᴋᴇʀ

Bạn có thể thay đổi m+''+tđể m+tlưu 3 byte, nếu tôi không nhầm.
Sherlock9

Bạn nói đúng, tôi bắt đầu m+' '+tnhập một khoảng trắng giữa chúng, nhưng sau khi đọc lại mô tả, tôi đã xóa khoảng trắng nhưng không phải là '' và +
levanth

2

C #, 63

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

Tốt hơn Java :)

Mã kiểm tra:

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

Đầu ra:

a

ba
b
b
ba


2

Jolf, 12 byte

?=iγρiIE+iIγ

Hoặc, nếu chúng ta phải bao gồm các ký tự nhạy cảm regex:

?=iγρiLeIE+iIγ

Hãy thử nó ở đây!

Giải trình

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

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

Hơi ngắn hơn câu trả lời của @ nobe4 bằng cách tận dụng sự chia tách và tham gia


2

Vợt, 70 byte

Khá thẳng về phía trước.

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

2

Scala, 72 70 byte

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

Thông dịch viên trực tuyến: www.tryscala.com


1
Chào mừng bạn đến với Câu đố lập trình & Code Golf! Tôi không biết Scala, nhưng tôi nghĩ bạn có thể xóa khoảng trống xung quanh if(r==m).
Dennis

Vâng bạn đúng
Avis


1

Perl, 37 30 byte

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

Các biểu thức chính quy bên trong chuỗi chuyển đổi không được đánh giá do trích dẫn với \Q ... \E.

sub F\E được gỡ bỏ theo nhận xét của msh210.

Nó không hoàn toàn không có tác dụng phụ vì cài đặt $_. Sử dụng một biến cục bộ sẽ tốn thêm sáu byte:

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

Mặt khác, với các tham số đầu vào được chuyển đổi, hai byte có thể được lưu bằng cách sử dụng popthay vì shift(28 byte):

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

Hồ sơ kiểm tra:

#!/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__

Kết quả kiểm tra:

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 nói "Chữ ký là một phần của cơ thể của chương trình con. Thông thường, phần thân của chương trình con chỉ đơn giản là một khối mã." Vì vậy, bạn có thể bỏ qua sub Fsố byte của bạn. Ngoài ra, bạn sẽ có thể sử dụng popthay vì shift(bằng cách đảo ngược thứ tự của các đầu vào, natch), tiết kiệm hai byte. (Chưa được kiểm tra.) Cuối cùng, bạn sẽ có thể bỏ qua \E, lưu thêm hai byte. (Cũng chưa được kiểm tra.)
msh210

@ msh210 Cảm ơn, mẹo của bạn đã lưu bảy byte. Tôi không thấy, làm thế nào popthay vì shiftcó thể giúp đỡ, bởi vì $_nên là đối số đầu tiên cần tránh $_[1]=~s/.../. Thứ tự của các đối số đầu vào được cố định bằng câu hỏi AFAIK.
Heiko Oberdiek

Thứ tự của các đối số đầu vào không được cố định bởi câu hỏi afaict.
msh210

1

C # (58 byte)

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

Nó sử dụng một phép gán nội tuyến để tắt một vài byte


Xin chào, và chào mừng đến với PPCG! Bài đăng đầu tiên tuyệt vời! Tôi không sử dụng C # nhiều, nhưng bạn không thể làm var s,thay var s,var tthay vào đó string?
NoOneIsHere 22/05/2016

Cảm ơn! Đáng buồn là varchỉ có thể được sử dụng ở những nơi mà loại được biết đến vào thời gian biên dịch, vì vậy nó không thể được sử dụng trong chữ ký phương thức. Bạn có thể sử dụng dynamic, nhưng nó dài hơn 1 ký tựstring
Blue0500

Thế còn var F(string s, string t? Điều đó có thể được suy ra ...
NoOneIsHãy

1

bash + sed, 28 byte

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

Kịch bản lệnh nằm trong tệp toggle-string.bash mà chúng ta gọi bằng bash toggle-string.bash mainstring togglestring .

s/$2//g xóa chuỗi chuyển đổi khỏi chuỗi chính

t nhảy đến cuối nếu sự thay thế trước đó thành công (ví dụ: chuỗi chính chứa chuỗi chuyển đổi)

/$/$2/thêm chuỗi chuyển đổi ở cuối ( $), nếu chúng ta không nhảy đến cuối

bash là cần thiết cho việc di truyền


Điều này sẽ không hoạt động nếu chuỗi chuyển đổi có chứa các ký tự đặc biệt.
Dennis


0

PowerShell v2 +, 47 byte

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

Đưa đầu vào $a,$bvà sau đó sử dụng (... , ...)[...]câu lệnh giả ba chiều để thực hiện if / other. Các phần bên trong được đánh giá đầu tiên để tạo thành một mảng gồm hai phần tử. Số 0 là $avới tất cả các lần xuất hiện của $b -replaced không có gì, được lưu trữ vào $c. Đầu tiên chỉ là một chuỗi nối $a$b .

Nếu $c-equal to $a, nghĩa $blà không tìm thấy, đó là Boolean $truehoặc 1, và do đó, phần tử đầu tiên của mảng (phần nối) được chọn. Khác, đó là Boolean $false, vì vậy chúng tôi đầu ra$c , phần tử thứ 0.

Lưu ý rằng đó -replacelà tham lam, vì vậy nó sẽ thay thế từ bên trái đầu tiên, có nghĩa là ababa / abatrường hợp thử nghiệm sẽ trở lại đúng ba.



0

Ruby, 33 byte 27 byte (28 nếu sử dụng phép trừ toàn cầu) chắc chắn là 28 byte

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

0

Toán học, 45 byte

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

Hàm ẩn danh nhận chuỗi chính và chuỗi chuyển đổi (theo thứ tự đó) và trả về kết quả. Giải trình:

                                            &  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 byte

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

Có thể đọc được

   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 byte với đầu vào đúng 1 ký tự

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

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

Xin chào, và chào mừng đến với PPCG! Câu trả lời chính xác!
NoOneIsHãy là


0

Ruby, 35 37 28 byte

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

Hoan hô cho nội suy chuỗi! Nó thậm chí hoạt động trong regexes. Phần còn lại rất đơn giản: nếu chuỗi trong tkhớp với m, thay thế tbằng '', trả về m+t.

Chỉnh sửa: Đã sửa lỗi.

Chỉnh sửa: Tôi đã áp dụng đề xuất của Kevin Lau, nhưng có vẻ như tôi đã đạt được thuật toán tương tự như thuật toán được sử dụng trong câu trả lời của Luis Masuelli .


Điều này có thể thất bại nếu chuỗi chuyển đổi có chứa các ký tự đặc biệt. Ví dụ, ("a", ".")trả về "a"thay vì "a.".
Dennis

m[t]ngắn hơn nhiều so với m.include?(t)và vẫn kiểm tra để đưa vào trong chuỗi.
Mực giá trị

0

k (23 byte)

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

Ví dụ:

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 byte

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

Điều này sẽ ngắn hơn nếu phép gán là một biểu thức trong Kotlin và các tham số có thể thay đổi và có một toán tử điều kiện tạm thời, đáng buồn thay, đây không phải là trường hợp :(

Hãy thử trực tuyến!

Vô duyên

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.