递归字符串替换


25

任务

编写一个程序或函数,给出给定的三个字符串A, B, C会生成一个输出字符串,其中Bin的每个实例A都已用递归替换C。递归替换表示重复替换,其中在每一步中Bin的所有不重叠实例A(从左到右贪婪地选择)都替换为,C直到B不再包含在中A

输入输出

  • 您可以对I / O使用任何默认方法
  • 字符串将仅包含可打印的ASCII字符(并且可以包含任何一个)。
  • B永远不会是一个空字符串,而A并且C可能是。
  • 字符串应被视为纯文本,例如,您不能将其B视为Regex模式。
  • 输入的某些组合永远不会终止。在这种情况下,您的程序可以执行任何操作。

测试用例

这些格式为: 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}
)

不会终止的示例:

grow/ow/oow

loop/lo/lo

3
另一个测试案例:((())())())/()/
Conor O'Brien

@ ConorO'Brien添加了
Leo

1
起初,我没有使其区分大小写。downpercase is down
Engineer Toast

Answers:


7

05AB1E,2个字节

`:

在线尝试!

说明

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

如果我们不必处理空字符串,则可:以为1个字节


3
如果我正确理解,则您的4字节解决方案有效。“输入的某些组合永远不会终止。在这种情况下,您的程序可以执行任何操作。”
Leo

@Leo。你是对的。我略过了这一部分:)
艾米娜(Emigna)'17

1
那么从根本:上讲,内置函数可以解决所有挑战吗?我应该禁止内置的;)
Leo

@Leo:如果不是空字符串,那么内置一个就可以解决。与空字符串的唯一区别是,我们需要指定有3个输入,否则将由操作隐式推断出:)
Emigna

是像这样也可以吗?
阿德南

9

Python 2,43个字节

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

在线尝试!

计算以下形式的字符串

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

为了达到一个固定点(如果存在的话),足以进行等于原始字符串长度的替换。


7

ES6(JavaScript), 47,43字节

  • 使用currying保存了4个字节(感谢@Neil!)

打高尔夫球

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

试试吧

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"/>


您可以通过以相反的顺序传递参数来节省4个字节: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哦,我知道了。
Metoniem

5

视网膜,27字节

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

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

输入应以换行分隔。

在线尝试!(为方便起见,使用测试套件输入格式,其中每行都是用斜杠分隔的测试用例。)


4

C#,44个字节

简洁版本:

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

示例程序:

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

说明: 该函数编写为尾部递归表达式,通过利用以下内容避免了return关键字和大括号:

  • 括号内的赋值返回赋值
  • 相等检查的左侧将在右侧分配之前进行评估,从而使我们可以在内联之前/之后进行比较,并且仍然可以访问结果

这使我们将其保持为单个语句。

编辑: 回去省略函数r的类型,因为这似乎可以接受。使用数组声明类型时,为68个字符。没有,它是44个字符。


如果该函数仅在给定特定名称的情况下才起作用,则需要花一些字节为该函数命名。r=对于声明来说,这是2个字节还是更多个字节,这对我来说不是立即显而易见的(部分原因是我不完全了解规则,部分原因是我不太了解C#来应用它们)。

是的,我在阅读了其他人对另一个条目的评论后,正在解决这个问题。还有很多,因为必须全部指定类型。我转而使用数组进行保存,并在递归调用中保存字节。
丹尼尔(Daniel)

您的意思是不产生正确的输出?我认为您不需要输出输入,实际上,其他一些答案也没有。我是否错过了一条评论,说我需要输出输入?
auhmaan

没关系,我发现了问题,它不是递归的。
auhmaan

2

Japt,15个字节

@¥(U=UqV qW}a@U

在线测试!

怎么运行的

@¥(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具有内置的递归替换,但它将第一个输入视为正则表达式。如果保证输入仅包含字母数字字符,则此三字节解决方案将起作用:

eVW

如果输入被允许包含任何炭除^\],这12字节的溶液将是有效的,而不是:

eV®"[{Z}]"ÃW

2

C#,33个 49字节

可能是用C#编写的最小片段之一...而且由于Replace是该string结构的本机,因此不需要usings(至少不需要VS内置功能C#Interactive ...

另外,由于B始终具有值,因此代码不需要任何验证。


打高尔夫球

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

不打高尔夫球

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

    return a;
}

完整代码

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

发布

  • V1.1 - +19 bytes-固定的解决方案不是递归。
  • 1.0 -  33 bytes-初始溶液。

1
我看到c#我
赞成投票

@NelsonCasanova听起来像我。
Metoniem '17

是否Replace执行递归替换?
Laikoni '17

@Laikoni没有 例如,"((())())())".Replace("()", "")return (()))
auhmaan

那么根据挑战的规则,该解决方案是无效的。您应该删除它以防止投票不足,然后修复您的解决方案以处理递归替换,最后取消删除它。
Laikoni '17

1

处理中,75 72字节

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

打印结果。像这样称呼它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

Mathematica,35个32字节

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

参数以序列形式给出。永远不会终止的grow例子,退货looploop例子。感谢马丁的建议,减少了三个字节。


FixedPoint往往太长,可以用//.以下方法来模仿:#//.x_:>StringReplace[x,#2->#3]&
Martin Ender

谢谢@MartinEnder。这是开始使用ReplaceRepeated弦乐的好方法!
西蒙斯(Simmons)

顺便说一句,这只会循环$RecursionLimit时间,2^16默认情况下,不会影响您的答案
ngenisis

@ngenesis我不知道,ReplaceRepeated通过控制$RecursionLimit-我只是测试它通过限制设置为20,该项目仍快乐地用于非终止输入循环..
西蒙斯

因为ReplaceRepeated有一个单独的选项(不能与//.语法一起使用),称为MaxIterations默认为2 ^ 16。(cc @ngenisis)
Martin Ender

1

Ruby,29个字节

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

给定3个参数,对第一个参数应用替换,直到不再有替换。

说明

  • 1之前while只是点头
  • gsub!返回字符串,或者nil如果没有替换发生


1

///,3个字节

///

将字符串B放在第一个斜杠之后,将C放在第二个斜杠之后,并将A放在末尾,即:

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

在线尝试!


我认为这不是接受输入的可接受方式
Leo

据我所知,///不接受任何其他方式的输入。
steenbergh

2
好吧,我认为讨论这是否可以接受是很有趣的,然后:)无论如何,我注意到您提交的另一个问题:如果/任何输入字符串中都存在a,则不起作用
Leo

1

JavaScript(Firefox 48或更早版本),43字节

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

以相反的顺序处理参数。Firefox曾经有一个非标准的第三个参数,replace为其指定了regexp标志。此参数已在Firefox 49中删除。


0

SmileBASIC,72 68字节

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

在SmileBASIC中,实际上很少执行功能的情况之一。


0

Javascript 130字节

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

如果您给它一个正则表达式,则Javascript只会同时替换所有它们。为了使此正则表达式适用于所有值,需要将所有用于正则表达式的字符替换为转义版本。最后,对replace进行评估,以用C替换A中的所有B实例,并将其再次传递回该函数。



0

Cheddar,37个字节

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

在电话上,因此很难添加TIO链接。基本上在a中检查b时使用递归。解决方案可能是有效的,(a,b,c)->a.sub(Regex{b,"cr"},c)但由于某种原因无法正常工作。


sub会取代全部还是仅取代第一个?
fəˈnɛtɪk

@LliwTelracs,因为它们是字符串.sub将替换全部
Downgoat

这似乎行不通吗?在线尝试!
科纳·奥布赖恩

@ ConorO'Brien废话三元愚蠢的错误侧已关闭
Downgoat

0

Perl 6,40个字节

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

尝试一下(如果更新了tio.run)
尝试更改版本

展开:

{
  $^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

Java-157字节

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

对于空输入,它将返回一个空字符串。

空或像这样的数据输入StackOverflowExceptionB会因错误崩溃A/A/A

怎么运行的:

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

带注释的非高尔夫代码:

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

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

%1%%2%%3%是传递给函数的前三个参数。
如果函数需要一个变量参数,则将%s删除。
区分大小写设置的开销为19个字节,但如果没有它,则会得到downpercase is down

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.