Thay thế chuỗi đệ quy


25

Nhiệm vụ

Viết chương trình hoặc hàm cho ba chuỗi A, B, Ctạo ra một chuỗi đầu ra trong đó mỗi trường hợp Btrong Ađã được thay thế đệ quy bằng C. Đệ quy thay thế phương tiện lặp lại thay một nơi ở mỗi bước tất cả các trường không chồng chéo của Btrong A(chọn tham lam từ trái sang phải) đều được thay thế bằng Ccho đến khi Bkhông hơn chứa trong A.

Đầu ra đầu vào

  • Bạn có thể sử dụng bất kỳ phương pháp mặc định cho I / O .
  • Chuỗi sẽ chỉ chứa các ký tự ASCII có thể in (và có thể chứa bất kỳ ký tự nào trong số chúng).
  • Bsẽ không bao giờ là một chuỗi rỗng, trong khi ACcó thể là.
  • Các chuỗi được coi là bản rõ, ví dụ, bạn không thể coi Blà một mẫu Regex.
  • Một số kết hợp đầu vào sẽ không bao giờ chấm dứt. Chương trình của bạn có thể làm bất cứ điều gì trong những trường hợp đó.

Các trường hợp thử nghiệm

Đây là trong định dạng: A/B/C\nOutput

Hello, world!/world!/PPCG
Hello, PPCG

Uppercase is up/up/down
Uppercase is down

ababababa/aba/ccc
cccbcccba

delete/e/{empty string}
dlt

{empty string}/no/effect
{empty string}

llllrrrr/lr/rl
rrrrllll

+-+-+-+/+-+/+
+

ababababa/aba/bada
badabbadbada

abaaba/aba/ab
abb

((())())())/()/{empty string}
)

Các ví dụ không chấm dứt:

grow/ow/oow

loop/lo/lo

3
Một trường hợp thử nghiệm khác:((())())())/()/
Conor O'Brien

@ ConorO'Brien đã thêm
Leo

1
Lúc đầu, tôi thất bại trong việc phân biệt chữ hoa chữ thường. downpercase is down
Kỹ sư Toast

Câu trả lời:


7

05AB1E , 2 byte

`:

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

Giải trình

`    # split input to stack
 :   # replace (until string doesn't change)

Điều này có thể :cho 1 byte nếu chúng ta không phải đối phó với chuỗi rỗng.


3
Nếu tôi hiểu chính xác, giải pháp 4 byte của bạn là hợp lệ. "Một số kết hợp đầu vào sẽ không bao giờ chấm dứt. Chương trình của bạn có thể làm bất cứ điều gì trong những trường hợp đó."
Leo

@Sư Tử. Bạn đúng. Tôi lướt qua phần đó :)
Emigna

1
Vì vậy, về cơ bản :là một dựng sẵn để giải quyết toàn bộ thách thức? Tôi nên đã cấm các nội dung;)
Leo

@Leo: Nếu không có chuỗi trống, một chuỗi tích hợp sẽ giải quyết điều này có. Và sự khác biệt duy nhất với các chuỗi rỗng là chúng ta cần xác định rằng có 3 đầu vào, nếu không thì sẽ được suy luận ngầm bằng thao tác :)
Emigna

Là một cái gì đó như thế này cũng có thể?
Ad Nam

9

Python 2 , 43 byte

lambda s,*l:eval('s'+'.replace(*l)'*len(s))

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

Đánh giá một chuỗi các hình thức

s.replace(*l).replace(*l).replace(*l) ...

Để đạt đến một điểm cố định nếu tồn tại, nó đủ để thay thế bằng độ dài của chuỗi gốc.


7

ES6 (Javascript), 47, 43 byte

  • Đã lưu 4 byte bằng cách sử dụng currying (Cảm ơn @Neil!)

Chơi gôn

c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)

Thử nó

Q=c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)

function doit() {
  console.log(Q(C.value)(B.value)(A.value));
}
A: <input type="text" value="abaaba" id="A"/> B: <input type="text" value="aba" id="B"/> C: <input type="text" value="ab" id="C"/> <input type="submit" onclick="doit();" value="REPLACE"/>


Bạn có thể lưu 4 byte bằng cách sắp xếp các đối số theo thứ tự ngược lại:c=>b=>g=a=>a==(a=a.split(b).join(c))?a:g(a)
Neil


@MetoniemSome combinations of inputs will never terminate. Your program can do anything in those cases.
zeppelin

@zeppelin ơi, tôi hiểu rồi.
Metoniem

5

Võng mạc , 27 byte

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

+`(.+)(?=.*¶\1¶(.*))
$2
G1`

Đầu vào phải được phân tách theo dòng.

Hãy thử trực tuyến! (Để thuận tiện, hãy sử dụng định dạng đầu vào của bộ thử nghiệm trong đó mỗi dòng là một trường hợp thử nghiệm được phân tách bằng dấu gạch chéo.)


4

C #, 44 byte

Phiên bản ngắn:

r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);

Chương trình ví dụ:

using System;

namespace ConsoleApplication1
{
    class Program
    {
    static void Main(string[] args)
        {
            Func<string, string, string, string> r = null;
            r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);

            Action <string, string, string, string> test =
                (a, b, c, answer) =>
                {
                    var result = r(a, b, c);
                    Console.WriteLine("A: \"{0}\"\r\nB: \"{1}\"\r\nC: \"{2}\"\r\nResult: \"{3}\"\r\n{4}\r\n\r\n",
                        a, b, c, result, result == answer ? "CORRECT" : "INCORRECT"
                        );
                };

            test("Hello, world!", "world!", "PPCG", "Hello, PPCG");
            test("Uppercase is up", "up", "down", "Uppercase is down");
            test("ababababa", "aba", "ccc", "cccbcccba");
            test("delete", "e", "", "dlt");
            test("", "no", "effect", "");
            test("llllrrrr", "lr", "rl", "rrrrllll");
            test("+-+-+-+", "+-+", "+", "+");
            test("ababababa", "aba", "bada", "badabbadbada");
            test("abaaba", "aba", "ab", "abb");
            test("((())())())", "()", "", ")");


            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
    }
}

Giải thích: Hàm được viết dưới dạng biểu thức đệ quy đuôi, tránh từ khóa trả về và dấu ngoặc nhọn bằng cách khai thác các mục sau:

  • Một phép gán trong ngoặc đơn trả về giá trị được gán
  • Phía bên trái của kiểm tra đẳng thức sẽ được đánh giá trước khi gán bên phải, cho phép chúng tôi so sánh trước / sau nội tuyến và vẫn truy cập kết quả

Điều này cho phép chúng tôi giữ nó cho một tuyên bố duy nhất.

EDIT: Đã quay trở lại bỏ qua loại chức năng r, vì điều đó dường như được chấp nhận. Với khai báo kiểu sử dụng mảng, nó là 68 ký tự. Không có, nó là 44 ký tự.


Nếu hàm sẽ chỉ hoạt động nếu được cung cấp một tên cụ thể, bạn sẽ cần phải sử dụng các byte để cung cấp cho tên đó. Nó không rõ ràng ngay lập tức cho dù đó là 2 byte chor= nhiều hơn cho một khai báo (một phần vì tôi không biết đầy đủ các quy tắc, một phần vì tôi không biết rõ về C # để áp dụng chúng).

Vâng, tôi chỉ sửa nó sau khi đọc bình luận của người khác về một mục khác. Và nó là nhiều hơn nữa, vì tất cả các loại phải được chỉ định. Tôi chuyển sang sử dụng một mảng để lưu vào đó và lưu byte vào cuộc gọi đệ quy.
Daniel

Bạn có ý nghĩa gì với việc không tạo ra đầu ra chính xác ? Tôi không nghĩ rằng bạn cần phải xuất đầu vào, trên thực tế, một số câu trả lời khác không làm điều đó. Tôi đã bỏ lỡ một bình luận nói rằng tôi cần phải xuất đầu vào?
auhmaan

Không bao giờ, tôi đã tìm thấy vấn đề, nó không phải là đệ quy.
auhmaan

2

Japt , 15 byte

@¥(U=UqV qW}a@U

Kiểm tra nó trực tuyến!

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

@¥(U=UqV qW}a@U  // Implicit: U, V, W = input strings
            a@U  // Return the first non-negative integer mapped by the function X => U
@          }     // that returns truthily when mapped through this function:
     UqV qW      //   Split U at instances of V, and rejoin with W.
  (U=            //   Set U to this new value.
 ¥               //   Return (old U == new U). This stops the loop when U stops changing.
                 // Implicit: output result of last expression

Japt có tích hợp thay thế đệ quy, nhưng nó xem đầu vào đầu tiên là biểu thức chính quy. Nếu các đầu vào được đảm bảo chỉ chứa các ký tự chữ và số, giải pháp ba byte này sẽ hoạt động:

eVW

Nếu đầu vào được phép chứa bất kỳ char nào ngoại trừ ^ , \hoặc ], giải pháp 12-byte này sẽ có giá trị thay vì:

eV®"[{Z}]"ÃW

2

C #, 33 49 byte

Có lẽ, một trong những đoạn nhỏ nhất được viết bằng C # ... Và vì Replacecó nguồn gốc từ stringcấu trúc, nên không cần usings ( Ít nhất là không có trên tính năng tích hợp sẵn của VS, C # Interactive ... )

Ngoài ra, vì Bluôn có một giá trị, mã không cần bất kỳ xác nhận hợp lệ nào.


Chơi gôn

(a,b,c)=>{while(a!=(a=a.Replace(b,c)));return a;}

Bị đánh cắp

(a, b, c) => {
    while( a != ( a = a.Replace( b, c ) ) );

    return a;
}

Mã đầy đủ

using System;

namespace Namespace {
    class Program {
        static void Main( string[] args ) {
            Func<string, string, string, string> func = (a, b, c) => {
                // Recursively ( now truly recursive ) replaces every 'b' for 'c' on 'a',
                // while saving the value to 'a' and checking against it. Crazy, isn't it?
                while( a != ( a = a.Replace( b, c ) ) );

                return a;
            };

            int index = 1;

            // Cycle through the args, skipping the first ( it's the path to the .exe )

            while( index + 3 < args.Length ) {
                Console.WriteLine( func(
                    args[index++],
                    args[index++],
                    args[index++]) );
            }

            Console.ReadLine();
        }
    }
}

Phát hành

  • v1.1 - +19 bytes- Giải pháp cố định không được đệ quy.
  • v1.0 -  33 bytes- Giải pháp ban đầu.

1
Tôi thấy c # I upvote
Nelz

@NelsonCasanova Nghe giống tôi.
Metoniem

Replacethực hiện thay thế đệ quy?
Laikoni

@Laikoni không. Ví dụ, "((())())())".Replace("()", "")trả về (())).
auhmaan

Sau đó, giải pháp này không hợp lệ theo các quy tắc của thách thức. Bạn nên xóa nó để ngăn chặn downvote, sau đó sửa giải pháp của bạn để xử lý thay thế đệ quy và cuối cùng phục hồi nó.
Laikoni

1

Đang xử lý, 75 72 byte

void g(String a,String[]s){for(;a!=(a=a.replace(s[0],s[1])););print(a);}

In kết quả. Gọi nó như thếg("llllrrrr", new String[]{"lr","rl"});

void Q110278(String a, String[]s){             //a is the string to be replaced
                                               //s is the array containing the subsitution

  for(; a!=                                    
            (a = a.replace(s[0], s[1])) ;);

  //for-loop where we continuously perform substitution on a
  //until a is equal to substituted a


  //at the end, print the final version of a
  print(a);
}

1

Toán học, 35 32 byte

#//.x_:>StringReplace[x,#2->#3]&

Các đối số được đưa ra như một chuỗi. Không bao giờ chấm dứt cho growví dụ, lợi nhuận loopcho loopví dụ. Giảm ba byte nhờ đề nghị của Martin.


FixedPointcó xu hướng quá dài và có thể được mô phỏng với //.:#//.x_:>StringReplace[x,#2->#3]&
Martin Ender

Cảm ơn @MartinEnder. Đó là một cách tốt ReplaceRepeatedđể làm việc cho chuỗi!
Một Simmons

btw, điều này sẽ chỉ lặp lại $RecursionLimitthời gian, mà 2^16theo mặc định, không ảnh hưởng đến câu trả lời của bạn
ngenisis

@ngenesis Tôi không chắc chắn điều đó ReplaceRepeatedđược kiểm soát bởi $RecursionLimit- Tôi chỉ kiểm tra nó bằng cách đặt giới hạn thành 20 và chương trình vẫn vui vẻ lặp lại cho đầu vào không kết thúc ..
Một Simmons

Đối với ReplaceRepeatedmột tùy chọn riêng biệt (không thể được sử dụng với //.cú pháp), được gọi MaxIterations. Đó là mặc định là 2 ^ 16. (cc @ngenisis)
Martin Ender

1

Ruby, 29 byte

->a,b,c{1while a.gsub! b,c;a}

Đưa ra 3 đối số, áp dụng thay thế cho lần đầu tiên cho đến khi không còn gì để thay thế nữa.

Giải trình

  • 1trước khi whilechỉ đơn giản là một nop
  • gsub!trả về chuỗi hoặc nilnếu không có sự thay thế nào xảy ra


1

/// , 3 byte

///

Đặt chuỗi B sau dấu gạch chéo đầu tiên, C sau chuỗi thứ hai và A ở cuối, nghĩa là:

/<B>/<C>/<A>

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


Tôi không nghĩ rằng đây là một cách chấp nhận đầu vào
Leo

Theo hiểu biết của tôi, ///không chấp nhận đầu vào theo bất kỳ cách nào khác.
steenbergh

2
Chà, tôi nghĩ sẽ rất thú vị khi thảo luận xem điều này có được chấp nhận hay không, sau đó :) Dù sao, tôi đã nhận thấy một vấn đề khác với việc gửi của bạn: nó không hoạt động nếu /có mặt trong bất kỳ chuỗi đầu vào nào
Leo

1

JavaScript (Firefox 48 trở về trước), 43 byte

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

Đưa các đối số bị xáo trộn theo thứ tự ngược lại. Firefox đã từng có một tham số thứ ba không chuẩn replacemà chỉ định các cờ regrec. Tham số này đã bị xóa trong Firefox 49.


0

SmileBASIC, 72 68 byte

I=0DEF R A,B,C
I=INSTR(A,B)?A*(I<0)A=SUBST$(A,I,LEN(B),C)R A,B,C
END

Một trong những trường hợp hiếm hoi khi thực hiện một chức năng thực sự là SHORTER trong SmileBASIC.


0

Javascript 130 byte

f=(a,b,c)=>a.indexOf(b)<0?a:f(eval("a.replace(/"+b.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&")+"/g,c)"),b,c)

Javascript sẽ chỉ thay thế tất cả đồng thời nếu bạn cung cấp cho nó một biểu thức chính quy. Để làm cho regex này hoạt động cho tất cả các giá trị, tất cả các ký tự được sử dụng cho regex cần phải được thay thế bằng phiên bản thoát. Cuối cùng, sự thay thế được ước tính để thay thế tất cả các trường hợp của B trong A bằng C và chuyển lại xung quanh hàm đó một lần nữa.



0

Cheddar, 37 byte

(a,b,c)f->a has b?f(a.sub(b,c),b,c):a

Trên điện thoại nên liên kết TIO hơi khó thêm. Về cơ bản sử dụng đệ quy trong khi kiểm tra là b là trong a. Giải pháp có thể được (a,b,c)->a.sub(Regex{b,"cr"},c)nhưng không hoạt động vì một số lý do.


Liệu phụ thay thế tất cả hay chỉ là người đầu tiên?
fnɛtɪk

@LliwTelracs vì chúng là chuỗi .sub sẽ thay thế tất cả
Downgoat

Điều này dường như không hoạt động? Hãy thử trực tuyến!
Conor O'Brien

@ ConorO'Brien crap sai lầm ngớ ngẩn của ternary đã tắt
Downgoat

0

Perl 6 , 40 byte

{$^b;$^c;($^a,{S:g/$b/$c/}...*eq*)[*-1]}

Thử nó (nếu tio.run được cập nhật)
Hãy thử phiên bản đã thay đổi

Mở rộng:

{
  $^b;           # declare second parameter ( not used here )
  $^c;           # declare third parameter  ( not used here )

  (

    $^a,         # declare first parameter, and use it to seed the sequence

    {S:g/$b/$c/} # replace globally

    ...          # keep doing that

    * eq *       # until there are two that match

  )[*-1]
}

0

PHP, 46 byte

function g($a,$b,$c){echo strtr($a,[$b=>$c]);}

0

PHP, 102 byte

list($n,$s,$a,$b)=$argv;$f=str_replace($a,$b,$s);while($s!=$f){$s=$f;$f=str_replace($a,$b,$s);}echo$f;

Các trường hợp thử nghiệm (chức năng)

Trường hợp kiểm tra với lỗi vòng lặp


Chào! Thông thường, khi gửi một chức năng, bạn nên thêm vào bytecount tất cả những điều cần thiết cho chức năng được xác định (trong trường hợp của bạn function replace(...){...}, nếu không, việc gửi của bạn chỉ là một đoạn mã, không
Leo

@Leo Không biết điều đó, đã chỉnh sửa câu trả lời của tôi;)
roberto06

0

Java - 157 byte

String r(String f){if(f.length()<1)return "";String[]x=f.split("/");if(x[0].contains(x[1]))return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]);return x[0];}

Đối với đầu vào trống, nó trả về một chuỗi rỗng.

Sự cố với StackOverflowExceptionlỗi khi Btrống hoặc nó được cung cấp với dữ liệu như thế này A/A/A.

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

r("ABCD/A/F") returns value of r("FBCD/A/F") which returns FBCD
If there is no more characters to be replaced it returns the final output

Mã mã bị phản đối với ý kiến:

String r (String f) {
    if(f.length() < 1)
        return ""; // For empty input return empty output
    String[] x = f.split("/"); // Get all 3 parameters
    if (x[0].contains(x[1])) // If input contains replaced value
        return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]); // Return value of r() with one character replaced
    return x[0]; // If nothing to replace return the output(modified input)
}

0

AutoHotkey, 87 byte

StringCaseSense,On
Loop{
IfNotInString,1,%2%,Break
StringReplace,1,1,%2%,%3%
}
Send,%1%

%1%, %2%%3%là 3 đối số đầu tiên được truyền cho một hàm
Nếu một hàm mong đợi một đối số biến, %s bị loại bỏ
Thay đổi cài đặt phân biệt chữ hoa chữ thường có giá 19 byte, nhưng không có nó, bạn sẽ có được những thứ như thế downpercase is down.

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.