子序列替换


30

大多数语言都带有内置功能,可以在字符串中搜索所有出现的给定子字符串,然后用另一个替换。我不知道有什么语言可以将此概念推广为(不一定是连续的)子序列。因此,这就是您面临的挑战。

输入将包含三个字符串ABC,其中BC保证长度相同。如果B出现为子序列,A则应替换为C。这是一个简单的示例:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

可以这样处理:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

如果有几种查找子B序列的方法,则应贪婪地替换最左边的子序列:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

如果B可以在多个不相交的地方找到,则同样适用:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

B没有出现时A,您应该输出A不变。

规则

如上所述,采取三个串ABC作为输入和替换的最左边的发生B在作为子AC,如果有的话。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行参数或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

您可以按照在答案中指定的任何一致顺序选择三个字符串。您可以假设BC具有相同的长度。所有字符串将仅包含字母数字字符。

适用标准规则。

测试用例

每个测试用例是四行:ABC随后的结果。

abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

abcdeedcba
ada
BOB
BbcOeedcbB

abcdeedcbaabcde
ed
12
abcd1e2cbaabcde

121
121
aBc
aBc

abcde
acb
123
abcde

ABC
ABCD
1234
ABC

012345678901234567890123456789
42
TT
0123T5678901T34567890123456789

edcbaedcbaedcbaedcba
abcde
12345
edcbaedcbaedcbaedcba

edcbaedcbaedcbaedcbaedcba
abcde
12345
edcb1edc2aed3bae4cba5dcba

daccdedca
ace
cra
dcrcdadca

aacbcbabcccaabcbabcaabbbbca
abaaaccbac
1223334444
aacbcbabcccaabcbabcaabbbbca

aacbcbabcccaabcbabcaabbbbcac
abaaaccbac
1223334444
1ac2cb2bccc33b3bab4aa4bbbc44

排行榜

这篇文章底部的Stack Snippet通过答案a)生成了排行榜,a)是每种语言的最短解决方案列表,b)则是总体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


输入/输出的单个字符串列表是否合适?
FryAmTheEggman '16

@FryAmTheEggman嗯,我能找到的唯一共识是其中不涉及单字符字符串列表有效的字符串表示。可能值得发表一个元文章(特别是因为我认为这也是xnor的最新挑战之一)。我现在要说不。
Martin Ender

字符数组呢?似乎意味着即使该语言具有正确的字符串类型也允许它们。
丹尼斯

@Dennis是的,字符数组很好,但是单例字符串就像将整数数组作为[[1], [2], [3]]
Martin Ender

好的,谢谢您的清理。
丹尼斯

Answers:


3

果冻23 22 21字节

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?

在线尝试!请注意,最后两个测试用例将耗尽内存。

验证

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-short
while read s; do
        read p; read r; read o; echo $o; read
        timeout 1s jelly eun $1 "='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?" "'$s'" "'$p'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-short
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
(killed)
1ac2cb2bccc33b3bab4aa4bbbc44
(killed)

怎么运行的

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?  Main link. Arguments: string s, pattern p, replacement r

='                     Compare each character of s with each character of p.
                       This yields a 2D list. Each row corresponds to a char in p.
  T€                   Compute the truthy indices of each row, i.e., the indices
                       of all occurrences of that char in s.
   Œp                  Compute the Cartesian product of the lists of indices.
        $              Combine the two links to the left into a monadic chain:
      Ṣ€                 Sort each list of indices.
     f                   Filter, removing all non-sorted lists of indices.
         Ḣ             Head; take the first (sorted) list of indices.
          Ṭ            Truth; generate a list with 1's at those indices.
           œp³         Partition; split s at all 1's, removing those characters.
                  Ḋ?   If the partition has more than more than one element:
              ż⁵$        Zip the partition with r.
                 ³       Else, return s.

12

Python 2,88个字节

def f(a,b,c,o=""):
 for q in a:x=q==b[:1];o+=c[:x]or q;b=b[x:];c=c[x:]
 print[o,a][c>'']

接收三个字符串并将结果输出到STDOUT的函数。该函数只对字符串进行一次传递,获取适当的char并b,c随我们进行更新。

用于测试(替换后printreturn):

S = """
<test cases here>
"""

for T in S.split("\n\n"):
    A,B,C,D = T.split()
    assert f(A,B,C) == D

9

Java 7,141

我认为我可以做更多的事情,但是我现在必须运行。这只是一个简单的迭代/替换,将索引保留在A和B中。

char[]h(char[]a,char[]b,char[]c){char[]d=a.clone();int i=0,j=0,k=b.length;for(;i<a.length&j<k;i++)if(a[i]==b[j])d[i]=c[j++];return j==k?d:a;}

为您的愉悦留白:

char[]h(char[]a,char[]b,char[]c){
    char[]d=a.clone();
    int i=0,j=0,k=b.length;
    for(;i<a.length&j<k;i++)
        if(a[i]==b[j])d[i]=c[j++];
    return j==k?d:a;
}

Whitespaced是的,这是完全可读的
cat

不是吗 我添加多行缩进版本的主要原因是为了避免水平滚动,以便可以一次看到所有内容。内联空格并不重要; IMO
Geobits,2016年

[功能要求]还有更多空白
Alex A.


@Geobits如果可以,请在最后保存一个字节j<k?a:d
Xanderhall

7

Lua,121字节

简单的解决方案,gsub使我们可以对每个字符进行一次精确的迭代,并将其替换为字符串的新实例。

它通过3个命令行参数获取输入,并向STDOUT输出一个字符串。

a,b,c=...d=a:gsub(".",function(s)if b:find(s)then b=b:sub(2)x=c:sub(1,1)c=c:sub(2)return x end end)print(b~=''and a or d)

不打高尔夫球

a,b,c=...               -- unpack the arguments into a, b and c
d=a:gsub(".",function(s)-- iterate over each character of the first argument
  if b:find(s)then      -- if the current character is in the set b
    b=b:sub(2)          -- remove it from b
    x=c:sub(1,1)        -- save the replacement character in x
    c=c:sub(2)          -- remove it from c
    return x            -- replace the current character with x
  end
end)
print(b~=''             -- if b is empty, we replaced all the character
      and a or d)       -- so output the result of gsub, else, output the first argument

6

Python 3,127个字节。

感谢Katenkyo,节省了16个字节。

仍然在做些工作,男人比我想象的还要糟糕。

f=lambda a,b,c:a.replace(b[0],c[0],1)[:a.index(b[0])+1]+f(a[a.index(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else a

说明:Awww是的,递归。

测试用例:

assert f('abcdeedcba', 'ada', 'BOB') == 'BbcOeedcbB'
assert f('abcdeedcbaabcde', 'ed', '12') == 'abcd1e2cbaabcde'
assert f('012345678901234567890123456789', '42', 'TT') == '0123T5678901T34567890123456789'
assert f('ABC', 'ABCD', '1234') == 'ABC'

+1可打50高尔夫球,但请继续!这至少需要击败我的Java回答;)
Geobits,2016年

7
@Geobits是的,我以前从未输过Java。这是我最大的耻辱。
Morgan Thrapp '16

我不是很精通python,但是all(x in a for x in b)还检查b和a中的元素是否以相同的顺序出现,或者仅在它们出现在这里时才显示?
Katenkyo '16

@Katenkyo仅它们都在那儿,但是递归时,切片会照顾到订单。
Morgan Thrapp '16

还行,这不会return a.replace(b[0],c[0],1)[:l(b[0])+1]+f(a[l(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else a让您节省一些字节吗?
Katenkyo

5

Python 3.5,87个字节

import re
lambda s,p,r:re.sub('(.*?)'.join(p),'\g<%d>'.join(r)%(*range(1,len(r)),),s,1)

验证所有测试用例

怎么运行的

  • '(.*?)'.join(p) 建立与要替换的子序列及其元素之间的任何内容匹配的搜索模式。

    由于量词是惰性的,因此每个量词都(.*?)将匹配尽可能少的字符。

    对于模式ghost,构造的正则表达式为g(.*?)h(.*?)o(.*?)s(.*?)t

  • '\g<%d>'.join(r)%(*range(1,len(r)),) 使用字符串格式构建替换字符串。

    每个都像捕获n一样\g<n>指的是第n 捕获的组\n

    对于替换12345,构造的字符串为1\g<1>2\g<2>3\g<3>4\g<4>5

  • re.sub(...,...,s,1)在字符串中最多执行一次替换s


4

佩斯27

.xuXG.*HC,hSI#.nM*FxRcQ1zwQ

测试套件

该测试套件省略了后两种情况,因为它们将耗尽内存。此处使用的算法是查找第一个字符串中第二个字符串中每个字符的所有索引,然后查找这些索引的所有可能顺序,并仅采用排序顺序的索引。然后将其中的第一个按排序顺序用作第一个字符串中的索引列表,以使用第三个字符串中的值进行更新。

我觉得应该比.nM*F... 短一些


4

MATL,33字节

y!=[]0b"@n:!<@*fX<h5Mt?}.]]?iw(}x

在线尝试!

说明

y!      % Implicitly input first two strings. Duplicate the first and transpose
=       % Compare the two strings element-wise. Gives a 2D array with all combinations
[]      % Push empty array. Indices of matching elements will be appended to this
0       % Push a 0. This is the index of last character used up in first string
b       % Bubble up (rearrange elements in stack) to move 2D array to top
"       % For each column of that array (each char of the second string)
  @     %   Push current column
  n:!   %   Transform into column array of consecutive values starting from 1
  <     %   Compare with index of last character used up of first string
  @*    %   Push current column again. Multiply element-wise (logical AND)
  fX<   %   Find index of first matching character, or empty if there's none
  h     %   Append to array containing indices of matching elements
  5Mt   %   Push index of matching character again. Duplicate
  ?}    %   If it's empty
    .   %     Break loop
  ]     %   End if
]       % End for
        % The top of the stack now contains a copy of the index of last matching
        % character, or an empty array if there was no match
?       % If non-empty: all characters were matched
  i     %   Input third string
  w     %   Swap top two elements in stack
  (     %   Assign the characters of the third string to first string at found indices
}       % Else: the original string needs to be output
  x     %   Delete (partial) array of matching indices. Leave original string in stack
        % End if
        % Implicitly display (either modified string or original string)

3

JavaScript(ES6),84个字节

(a,b,c)=>[...b].every((q,i)=>r[p=a.indexOf(q,p)]=~p++&&c[i],p=0,r=[...a])?r.join``:a

解释/测试


3

JavaScript(ES6),84 76字节

(a,b,c)=>a.replace(RegExp([...b].join`(.*?)`),c.replace(/\B/g,(_,i)=>'$'+i))

因为我确定这是RegExp的工作。

编辑:感谢@MartinBüttner♦,节省了8个字节。

@KevinLau的Ruby答案的端口占用了82个字节:

([...a],[...b],[...c])=>(d=a.map(e=>e==b[0]?c.shift(b.shift()):e),b[0]?a:d).join``

我还尝试了递归RegExp解决方案,但占用了90个字节:

f=(a,[b,...d],[c,...e])=>b?a.replace(RegExp(b+'(.*'+d.join`.*`+'.*)'),(_,s)=>c+f(s,d,e)):a

3

朱莉娅,89 70字节

f(s,a,b,i=0)=(o=join(["$a "[i+1]!=c?c:b[i+=1]for c=s]);i<endof(a)?s:o)

使用索引i来遍历模式/替换字符串。-19个字节,感谢@Dennis!


2

C,98字节

char*f(i,o,s,r)char*i,*o,*s,*r;{char*I=i,*O=o;for(;*i;++i,++o)*o=*i==*s?++s,*r++:*i;return*s?I:O;}

/ *扩展代码* /

char *f(i, o, s, r)
    char *i, *o, *s, *r;
{
    char *I=i, *O=o;
    for (;  *i;  ++i,++o)
        *o = (*i==*s) ? (++s,*r++) : *i;
    return *s ? I : O;
}

参数是: NPUT串,ø安输出缓冲器,s ^操作搜索字符串,- [R eplacement。

记住输入和输出的开始之后,我们遍历输入,每当击中输入时替换并推进替换。最后,如果替换用完了,请返回输出缓冲区,否则返回未修改的输入。

/ *测试* /

struct T
{
    const char *input;
    const char *search;
    const char *replace;
    const char *expected;
};

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int i;
    static const struct T test[] = {
        { "abcdefghijklmnopqrstuvwxyz",
          "ghost",
          "12345",
          "abcdef12ijklmn3pqr45uvwxyz"},
        { "abcdeedcba",
          "ada",
          "BOB",
          "BbcOeedcbB"},
        { "abcdeedcbaabcde",
          "ed",
          "12",
          "abcd1e2cbaabcde"},
        { "121",
          "121",
          "aBc",
          "aBc"},
        { "abcde",
          "acb",
          "123",
          "abcde"},
        { "ABC",
          "ABCD",
          "1234",
          "ABC"},
        { "012345678901234567890123456789",
          "42",
          "TT",
          "0123T5678901T34567890123456789"},
        { "edcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcbaedcbaedcbaedcba"},
        { "edcbaedcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcb1edc2aed3bae4cba5dcba"},
        { "daccdedca",
          "ace",
          "cra",
          "dcrcdadca"},
        { "aacbcbabcccaabcbabcaabbbbca",
          "abaaaccbac",
          "1223334444",
          "aacbcbabcccaabcbabcaabbbbca"},
        { "aacbcbabcccaabcbabcaabbbbcac",
          "abaaaccbac",
          "1223334444",
          "1ac2cb2bccc33b3bab4aa4bbbc44"
        }
    };

    for (i = 0;  i < (sizeof test) / (sizeof test[0]);  ++i) {
        const struct T *t = test+i;
        char *out = malloc(strlen(t->input)+1);
        char *result = f(t->input, out, t->search, t->replace);
        if (strcmp(t->expected, result))
            printf("Failed test %d; result = \"%s\"\n", i, result);
    }
    return EXIT_SUCCESS;
}

2

R,76个字节

function(a,b,c){s=substr;for(x in 1:nchar(b)){a=sub(s(b,x,x),s(c,x,x),a)};a}

用于sub替换第一个比赛

不打高尔夫球

function(a,b,c){                    # function with 3 arguments as per description
  s=substr;                         # alias for substr (saves 1 byte)
   for(x in 1:nchar(b)){            # index 1 to number character in b
     a=sub(s(b,x,x),s(c,x,x),a)};   # replace first instance of b[x] in a  
                                    # with c[x] and reassign to a
 a}                                 # return a

2

C ++,204个字节

打高尔夫球

#include<iostream>
#include<string>
int main(){std::string a, b, c;std::cin>>a>>b>>c;int t=0;for(int x=0;x<b.length();x++){t=a.find(b[x],t);if(t!=-1){a.replace(t,1,c.substr(x,1));}}std::cout<<a;return 0;}

不打高尔夫球

#include<iostream>
#include<string>

int main()
{
    std::string a, b, c;
    std::cin>>a>>b>>c;
    int t = 0;
    for (int x=0;x<b.length();x++) {
        t = a.find(b[x], t);
        if (t != -1) {
            a.replace(t,1,c.substr(x, 1));
        }
    }
    std::cout<<a;
    return 0;
}

我认为您使用的std不足以保证使用using namespace std;。使用std::cinstd::coutstd::string会节省5个字节,因为这些似乎是该名称空间的唯一用途。
Value Ink 2016年

@KevinLau谢谢!您是非常正确的,我想到了这一点,但实际上并没有想到要节省字符。
Michelfrancis Bustillos

哦! 还有一点,因为它很重要。再次阅读您的代码后,我意识到您正在贪婪地替换bin 中每个字母的最左边出现a,但是后面的字母也必须在前面的字母之后。(看一下测试用例3并与您的输出进行比较,我想您会发现您的代码会abc21ed...在预期输出为abcd1e2...!时输出!)
Value Ink 2016年

在10分钟前的代码“ Adregffftd \ nA23 \ nzac \ n”的ideone C ++ 14编译器输入中,生成“ zdregffftd”而不是“ Adregffftd”的输出
RosLuP


2

Haskell,87个字节

x@((a,b):c)#(d:e)|a==d,([],z)<-c#e=([],b:z)|0<1=(d:)<$>x#e
x#y=(x,y)
a!b=snd.(zip a b#)

我注意到缺少Haskell答案,因此决定解决该问题。这定义了一个三元函数!,其参数顺序为pattern-replacement-string。 在这里尝试。

说明

辅助功能#接受一个x字符对列表(模式和替换)和一个字符串y。如果“模式”字符x形成的子序列y,则返回空列表,y并且每个模式字符都替换为对应的模式字符。否则,它返回一对(x,y)。功能!拉链图案和替换字符串成x,适用#x和所述第三串,并返回结果的第二组分。

x@((a,b):c)#(d:e)  -- First case of #: both arguments nonempty.
  |a==d,           -- If the pattern char matches the string's head,
   ([],z)<-c#e     -- and the pattern's tail is a subsequence of the string's tail,
  =([],b:z)        -- tack the replacement char to the recursion result.
  |0<1             -- Otherwise,
  =(d:)<$>x#e      -- recurse with the same pairs and tack string's head to result.
x#y=(x,y)          -- If either argument is empty, just pair them.

如果模式是字符串的子序列,则代码以O(n)时间运行,对字符串进行一次递归遍历,并在此过程中贪婪地构造替换项。但是,如果模式不是子序列,则在最坏的情况下它将以O(2 n时间运行。这是因为在模式和字符串具有匹配字符的每个位置处,该函数都会调用自身以检查模式是否实际上是子序列,发现其不是子序列,然后再次调用自身以实际计算结果。


2

JavaScript(ES6),100 95字节

(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

这是有效的JavaScript Lambda函数。输出为函数return。接受三个参数(a,b,c)。f=在开始处添加并调用like f(arg1,arg2,arg3)

f=(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

console.log(f(prompt("Value for A"),prompt("Value for B"),prompt("Value for C")))


欢迎来到PPCG!未命名的函数通常是可接受的,因此f=除非您的函数是递归的,否则您不需要,但是看起来并非如此。
Martin Ender

@MartinBüttner谢谢!:)更新了我的答案。
Arjun

不幸的是,如果a不包含模式,这将失败。我也不确定返回字符串数组是否可以接受。
丹尼斯

@丹尼斯我已经更新了解决方案。我认为现在是正确的。抱歉,这么晚才回复和更新。(我刚刚注意到您的评论,因此延迟了)
Arjun

@MartinEnder在浏览所有解决方案时,我发现这是不正确的。但是,我现在已纠正它;而且它短了五个字节(因为我没有打扰许多高尔夫球场;那时我是新手高尔夫球员;虽然:p并不代表我现在很棒)。抱歉,发布错误的解决方案。
Arjun


1

八度,97字节

function A=U(A,B,C)t=0;for s=B if p=find(A(t+1:end)==s,1) D(t=p+t)=~0;else return;end;end;A(D)=C;

遍历要替换的子序列;查找第一个字符的第一个出现的位置,查找其余字符串中的下一个字符,重复。有趣的一点是:

D(t=p+t)=~0

D(     )      %// D is a logical mask of characters to replace in the input string
  t=p+t       %// t is the current end of D 
              %// p is the location of the character to replace
              %// update t and use as index to grow D
        =~0   %// make it so, number 1

由于ideone仍不接受名称不是''的函数,因此我将在此处运行示例。为简洁起见,仅针对前几个测试用例显示输入。key是预期的输出,ans是函数的输出。

A = abcdefghijklmnopqrstuvwxyz
B = ghost
C = 12345
key = abcdef12ijklmn3pqr45uvwxyz
ans = abcdef12ijklmn3pqr45uvwxyz
A = abcdeedcba
B = ada
C = BOB
key = BbcOeedcbB
ans = BbcOeedcbB
A = abcdeedcbaabcde
B = ed
C = 12
key = abcd1e2cbaabcde
ans = abcd1e2cbaabcde
key = aBc
ans = aBc
key = abcde
ans = abcde
key = ABC
ans = ABC
key = 0123T5678901T34567890123456789
ans = 0123T5678901T34567890123456789
key = edcbaedcbaedcbaedcba
ans = edcbaedcbaedcbaedcba
key = edcb1edc2aed3bae4cba5dcba
ans = edcb1edc2aed3bae4cba5dcba
key = dcrcdadca
ans = dcrcdadca
key = aacbcbabcccaabcbabcaabbbbca
ans = aacbcbabcccaabcbabcaabbbbca
key = 1ac2cb2bccc33b3bab4aa4bbbc44
ans = 1ac2cb2bccc33b3bab4aa4bbbc44

那些意想不到的地方的八度音阶作业(D(t=...))让我感到困惑:-)
路易斯·门多

1
@LuisMendo哈哈...几乎就像是...一堆!:)
烧杯

1

Python 3,123字节

我想分享一种不同的方法,它要短几个字节。没有针对标准库/正则表达式的规则,对吗?

import re
j=''.join
m='(.*?)'
def f(A,B,C):
 *r,l=(re.findall(m+m.join(B)+'(.*)',A)or[[A]])[0]
 print(j(map(j,zip(r,C)))+l)

PS。这是我的第一次高尔夫。让我知道任何问题/改进。


1

Pyth,22个字节

|eJ:Ej"(.*?)"+E\$3s.iJ

Pyth编译器中验证所有测试用例。

背景

我们通过在模式后附加一个来构建正则表达式 $(.*?)在所有字符之间并将其放置在。此正则表达式将匹配要替换的子序列及其元素之间的任何内容,以及直到字符串末尾的所有内容。

由于量词是惰性的,因此每个量词都(.*?)将匹配尽可能少的字符。

对于模式幻影,构造的正则表达式为 g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$

如果模式与输入匹配,则内置 r<str><regex>3函数将返回一个数组,其中包含预匹配项(子序列之前的所有内容),所有捕获的组(子序列之间和之后的所有内容)以及后匹配项(空字符串)。

如果模式不匹配,则内置函数将返回包含原始输入的单例数组。

怎么运行的

|eJ:Ej"(.*?)"+E\$3s.iJQ  (implicit) Store the first line of input in Q.

             +E\$        Read the third line of input (pattern) and append '$'.
     j"(.*?)"            Join the result, separating by "(.*?)".
    E                    Read the third line of input (string).
   :             3       Match the string against the regex, as detailed above.
  J                      Save the returned array in J.
 e                       Extract the last element of J. This is an empty string
                         for a successful match or the original string.
|                        Logical OR; replace an empty string with the following:
                   .iJQ    Interleave J and the replacement.
                  s        Flatten the resulting array of strings.

1

果冻,23 个字节

Ṭœpż⁵
0ẋai1
⁴='-;ç\ñ⁴P?

这比我的其他Jelly回答长两个字节,但立即完成。在线尝试!

验证

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-fast
while read s; do
        read p; read r; read o; echo $o; read
        timeout 10s jelly eun $1 "Ṭœpż⁵¶0ẋai1¶⁴='-;ç\ñ⁴P?" "'$p'" "'$s'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-fast
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
aacbcbabcccaabcbabcaabbbbca
1ac2cb2bccc33b3bab4aa4bbbc44
1ac2cb2bccc33b3bab4aa4bbbc44

怎么运行的

⁴='-;ç\ñ⁴P?  Main link. Arguments: pattern p, string s, replacement r

⁴='          Compare each character of s with each character of p.
             This yields a 2D list. Each row corresponds to a char in p.
   -;        Prepend -1 to the 2D list, yielding a ragged array.
     ç\      Cumulatively reduce the array by the second helper link.
         P?  If the product of the resulting list is non-zero:
       ñ       Call the first helper link with the list and s as arguments.
        ⁴      Else, return s.


Ṭœpż⁵        First helper link. Arguments: L (list of indices), r (replacement)

Ṭ            Truth; generate a list with 1's at those indices.
 œp          Partition; split s at all 1's, removing those characters.
   ż⁵        Zip the partition with r.


0ẋai1        Second helper link. Arguments: n (integer), B (list of Booleans)

0ẋ           Generate a list of n zeroes.
  a          Perform logical AND with B.
             This zeroes out the with n elements of B.
   i1        Compute the first index of 1.


1

Java 7,102字节

void L(char[]s,char[]l,char[]r){for(int x=0,y=0;x<s.length&&y<l.length;x++)if(s[x]==l[y])s[x]=r[y++];}

详细 尝试这里

// String, Lookup, Replacement
void L(char[]s, char[]l, char[]r)
{
    for(int x=0, y=0; x < s.length && y < l.length; x++)
        if(s[x] == l[y])
            s[x] = r[y++];
}

1

朱莉娅93 90 86字节

f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)

如果必须单独测试比赛是否成功,那将破坏得分。替换将需要强制转换为Base.SubstitutionString,这可能不值得...

测试运行

julia> f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)
f (generic function with 1 method)

julia> f("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> f("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"

1

朱莉娅62 59 58字节

f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)

I / O是字符数组的形式。

验证

julia> f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)
f (generic function with 2 methods)

julia> F(s,p,r)=join(f([s...],[p...],[r...])) # string/char array conversion
F (generic function with 1 method)

julia> F("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> F("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"

1

PHP,130个 109字节

我还是希望它更短一些。""<如果B保证不包含3个字节,则可以节省3个字节0

for($s=($a=$argv)[1];""<$c=$a[2][$i++];)if($p=strpos(_.$s,$c,$p+1))$s[$p-1]=$a[3][$k++];echo$k<$i-1?$a[1]:$s;

从命令行获取参数。用运行-r

找到字符时替换它们;
如果所有字符都已替换,则打印副本;其他的。


1

Ruby,70 64 59 58字节

匿名函数。通过串走a建设有根据下一个字符替换中的字母一个新的字符串bc,那么如果所有字符b在年底用完,返回新构造的字符串,否则返回原始字符串。

@histocrat通过节省了6个字节gsub

感谢@Cyoce,节省了1个字节。

->a,b,c{i=0;s=a.gsub(/./){$&==b[i]?c[~-i+=1]:$&};b[i]?a:s}

在线尝试!


您可以-1+i+=1~-i+=1
Cyoce '17

0

Perl,80 + 1 = 81字节

带着-p旗帜跑

$a=join"(.*?)",split//,<>;$b.=$_." .\$".++$;."."for split//,<>;chop$b;s/$a/$b/ee

在线尝试!

该代码按程序生成搜索和替换正则表达式命令,然后在最后一行代码中执行该命令。

ghost一个示例中的字符串变为string g(.*?)h(.*?)o(.*?)s(.*?)t(.*?),这意味着g后面跟0或更多个字符,然后h跟着0或更多个字符,再跟等。*?量词表示搜索应该是非贪婪的,并且”中尽可能少的字符,而不是尽可能多的默认匹配。

12345然后将字符串转换为1 .$1.2 .$2.3 .$3.4 .$4.5 .$5,在执行正则表达式后对其进行评估。每个$1,$2,$3,$4,$5实际上都是从第一个字符串到捕获组(在括号中)的反向引用。


我建议这段代码节省一些字节:perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'。我自己提出了这个建议,但它与您的建议非常接近,因此我不会发布它,这将是两个非常接近的答案,但是可以随时编辑您的建议!
达达

刚刚尝试了一下,因为我看到它被列为与最近一个问题有关的“相关”问题。我得到的最好的是perl -E 'chomp(($f,$t,$s)=(<>));$f=join"(.*?)",split"",$f;@r=split"",$t;@t=shift@r;push@t,"\${",++$x,"}"for(@r);$t=join"",@t;say$s=~s/$f/$t/r;'
Will Crawford

0

Clojure,113个字节

#(apply str((reduce(fn[[b c r]a](if(=(first b)a)[(rest b)(rest c)(conj r(first c))][b c(conj r a)]))[%2%3[]]%)2))

一个基本的reduce,心里很不是滋味那些长firstrestconj函数调用。希望看到更好的方法。

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.