Thay thế sau đó


30

Hầu hết các ngôn ngữ đi kèm với một tích hợp để tìm kiếm một chuỗi cho tất cả các lần xuất hiện của một chuỗi con nhất định và thay thế các chuỗi bằng một chuỗi khác. Tôi không biết bất kỳ ngôn ngữ nào khái quát khái niệm này đến các phần tiếp theo (không nhất thiết phải liền kề). Vì vậy, đó là nhiệm vụ của bạn trong thử thách này.

Đầu vào sẽ bao gồm ba chuỗi A, BC, ở đâu BCđược đảm bảo có cùng độ dài. Nếu Bxuất hiện như là một sau trong Anó nên được thay thế bằng C. Đây là một ví dụ đơn giản:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

Nó sẽ được xử lý như thế này:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

Nếu có một số cách để tìm Bnhư một phần tiếp theo, bạn nên tham lam thay thế phần lớn nhất bên trái:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

Áp dụng tương tự nếu Bcó thể được tìm thấy ở nhiều nơi khác nhau:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

Khi Bkhông xuất hiện A, bạn nên xuất Akhông thay đổi.

Quy tắc

Như đã trình bày ở trên, mất ba chuỗi A, BCnhư là đầu vào và thay thế trái nhất xảy ra Bnhư một dãy ở Avới C, nếu có bất kỳ.

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Bạn có thể lấy ba chuỗi theo bất kỳ thứ tự nhất quán nào mà bạn nên chỉ định trong câu trả lời của mình. Bạn có thể giả định rằng BCcó cùng chiều dài. Tất cả các chuỗi sẽ chỉ chứa các ký tự chữ và số.

Luật tiêu chuẩn được áp dụng.

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

Mỗi trường hợp thử nghiệm là bốn dòng: A, B, Csau đó là kết quả.

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

Bảng xếp hạng

Đoạn trích Stack ở cuối bài này tạo ra bảng xếp hạng từ các câu trả lời a) dưới dạng danh sách các giải pháp ngắn nhất cho mỗi ngôn ngữ và b) dưới dạng bảng xếp hạng tổng thể.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

## Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

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

Nếu ở đó bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ phiên dịch), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

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

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích:

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


Một danh sách các chuỗi ký tự đơn có ổn cho đầu vào / đầu ra không?
FryAmTheEggman

@FryAmTheEggman Hừm, sự đồng thuận duy nhất tôi có thể tìm thấy là điều này không giải quyết danh sách các chuỗi ký tự đơn dưới dạng biểu diễn chuỗi hợp lệ. Có thể đáng để tạo một bài đăng meta (đặc biệt bởi vì tôi nghĩ rằng điều này cũng xuất hiện trong thử thách mới nhất của xnor). Tôi sẽ nói không ngay bây giờ.
Martin Ender

Còn mảng nhân vật thì sao? Điều này dường như ngụ ý họ được phép ngay cả khi ngôn ngữ có loại chuỗi thích hợp.
Dennis

@Dennis Vâng, mảng ký tự là tốt, nhưng chuỗi singleton giống như lấy một mảng các số nguyên như [[1], [2], [3]].
Martin Ender

OK, cảm ơn vì đã xóa nó lên.
Dennis

Câu trả lời:


3

Thạch , 23 22 21 byte

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

Hãy thử trực tuyến! Lưu ý rằng hai trường hợp kiểm tra cuối cùng sẽ hết bộ nhớ.

xác minh

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

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

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

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

Một hàm lấy trong ba chuỗi và đưa kết quả về STDOUT. Hàm chỉ đơn giản là thực hiện một chuỗi trên chuỗi, lấy char phù hợp và cập nhật b,ckhi chúng ta đi.

Để thử nghiệm (sau khi thay thế printbằng return):

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

Tôi nghĩ có một số điều nữa tôi có thể làm với điều này, nhưng tôi phải chạy ngay bây giờ. Nó chỉ là một lần lặp / thay thế đơn giản, giữ một chỉ mục ở A và 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;}

Whitespaces cho niềm vui của bạn:

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

Whitespacedvâng, điều đó hoàn toàn có thể đọc được
con mèo

Có phải vậy không? Lý do chính tôi thêm phiên bản thụt lề nhiều dòng là để tránh cuộn ngang, để tất cả có thể được nhìn thấy cùng một lúc. Khoảng trắng nội tuyến không phải là một thỏa thuận lớn IMO;)
Geobits

[yêu cầu tính năng] thậm chí nhiều khoảng trắng hơn
Alex A.


@Geobits Lưu một byte vào cuối nếu bạn làmj<k?a:d
Xanderhall 7/12/2016

7

Lua, 121 byte

Giải pháp đơn giản, gsubcho phép chúng ta lặp lại chính xác một lần trên mỗi ký tự và thay thế chúng trong một thể hiện mới của chuỗi.

Nó nhận đầu vào thông qua 3 đối số dòng lệnh và xuất một chuỗi thành 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)

Ung dung

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

Đã lưu 16 byte nhờ Katenkyo.

Vẫn làm việc này một chút, con người nhanh hơn tôi nghĩ.

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

Giải thích: Awww yeah, đệ quy.

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

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 để chơi golf giảm 50, nhưng hãy tiếp tục! Điều này cần phải đánh bại câu trả lời Java của tôi ít nhất;)
Geobits

7
@Geobits Vâng, tôi chưa bao giờ thua Java trước đây. Đây là sự xấu hổ lớn nhất của tôi.
Morgan Thrapp

Tôi không thực sự thành thạo python nhưng all(x in a for x in b)cũng kiểm tra các yếu tố trong b và a xuất hiện theo cùng một thứ tự, hoặc chỉ khi chúng ở đây?
Katenkyo

@Katenkyo Chỉ có tất cả chúng ở đó, nhưng thứ tự được xử lý bằng cách cắt lát khi chúng tôi tái diễn.
Morgan Thrapp

Ok, ngoài ra, sẽ không 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 alàm cho bạn tiết kiệm một số byte?
Katenkyo

5

Python 3.5, 87 byte

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

repl.it để xác minh tất cả các trường hợp thử nghiệm .

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

  • '(.*?)'.join(p) xây dựng một mô hình tìm kiếm phù hợp với sự thay thế và bất cứ điều gì giữa các yếu tố của nó.

    Vì các bộ lượng hóa là lười biếng, mỗi cái (.*?)sẽ khớp với càng ít ký tự càng tốt.

    Đối với mẫu ghost, regex được xây dựng là g(.*?)h(.*?)o(.*?)s(.*?)t.

  • '\g<%d>'.join(r)%(*range(1,len(r)),) xây dựng chuỗi thay thế, sử dụng định dạng chuỗi.

    Mỗi \g<n>đề cập đến nhóm thứ n bị bắt, giống như sẽ.\n

    Để thay thế 12345, chuỗi được xây dựng là 1\g<1>2\g<2>3\g<3>4\g<4>5.

  • re.sub(...,...,s,1)thực hiện tối đa một thay thế trong chuỗi s.


4

Bình thường, 27

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

Phòng thử nghiệm

Bộ kiểm tra bỏ qua hai trường hợp cuối cùng vì chúng sẽ hết bộ nhớ. Thuật toán được sử dụng ở đây là tìm tất cả các chỉ mục của mỗi ký tự trong chuỗi thứ hai trong chuỗi thứ nhất, sau đó tìm tất cả các thứ tự có thể có của các chỉ số đó và chỉ lấy các chỉ số theo thứ tự được sắp xếp. Sau đó sử dụng một trong những thứ tự này theo thứ tự được sắp xếp làm danh sách các chỉ mục trong chuỗi đầu tiên để cập nhật với các giá trị từ chuỗi thứ ba.

Tôi cảm thấy nên có một cái gì đó ngắn hơn .nM*F...


4

MATL , 33 byte

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

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

Giải trình

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 byte

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

Giải thích / Kiểm tra


3

JavaScript (ES6), 84 76 byte

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

Bởi vì tôi chắc chắn rằng đây là một công việc cho RegExp.

Chỉnh sửa: Đã lưu 8 byte nhờ @ MartinBüttner ♦.

Một cổng của câu trả lời @ KevinLau Ruby mất 82 byte:

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

Tôi cũng đã thử một giải pháp RegExp đệ quy nhưng mất 90 byte:

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

3

Julia, 89 70 byte

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

Sử dụng một chỉ mục iđể lặp qua các chuỗi mẫu / chuỗi thay thế khi chúng ta đi. -19 byte nhờ @Dennis!


2

C, 98 byte

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

/ * Mã mở rộng * /

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

Các đối số là: i nput string, o utput buffer, s earch string, r eplocation.

Sau khi nhớ bắt đầu đầu vào và đầu ra, chúng tôi đi bộ đầu vào, thay thế và tiến lên thay thế bất cứ khi nào chúng tôi nhấn. Cuối cùng, nếu chúng ta hết thay thế, hãy trả lại bộ đệm đầu ra, nếu không thì đầu vào không được sửa đổi.

/ * Kiểm tra * /

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 byte

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

sử dụng subđể thay thế trận đấu đầu tiên

Ung dung

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 byte

Chơi gôn

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

Ung dung

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

Tôi không nghĩ rằng bạn đang sử dụng stdkhá đủ để đảm bảo sử dụng using namespace std;. Sử dụng std::cin, std::coutstd::stringsẽ tiết kiệm 5 byte vì những thứ đó dường như là cách sử dụng duy nhất của không gian tên đó.
Mực giá trị

@KevinLau Cảm ơn! Bạn rất đúng, tôi nghĩ về điều đó, nhưng thực tế không tính để nhận ra rằng nó sẽ tiết kiệm được ký tự.
Michelfrancis Bustillos

Oh! Một điều nữa, vì nó quan trọng. Sau khi đọc qua mã của bạn một lần nữa tôi nhận ra bạn đang tham lam thay thế sự xuất hiện trái nhất của mỗi chữ cái trong vòng btrong a, nhưng các chữ cái sau phải sau các chữ cái đầu là tốt. (Hãy xem trường hợp thử nghiệm 3 và so sánh với đầu ra của bạn, tôi nghĩ rằng bạn sẽ thấy rằng mã của mình sẽ xuất ra abc21ed...khi đầu ra dự kiến ​​là abcd1e2...!)
Ink Ink

Trong đầu vào trình biên dịch ideone C ++ 14 của "Adregffftd \ nA23 \ nzac \ n" ở trên mã 10 phút trước, hãy tạo đầu ra của "zdregffftd" thay vì "Adregffftd"
RosLuP


2

Haskell, 87 byte

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

Tôi nhận thấy thiếu câu trả lời của Haskell và quyết định sửa nó. Điều này xác định một hàm ternary !với chuỗi thay thế mẫu thứ tự đối số. Hãy thử nó ở đây.

Giải trình

Hàm phụ trợ #lấy danh sách xcác cặp ký tự (mẫu và thay thế) và một chuỗi y. Nếu các ký tự "mẫu" ở xdạng tiếp theo y, nó sẽ trả về danh sách trống và yvới mỗi ký tự mẫu được thay thế bằng đối tác của nó. Nếu không, nó trả về cặp (x,y). Hàm !nén mẫu và chuỗi thay thế vào x, áp dụng #cho xvà chuỗi thứ ba và trả về thành phần thứ hai của kết quả.

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.

Nếu mẫu là một chuỗi con của chuỗi, mã sẽ chạy trong thời gian O (n) , làm cho một lần đệ quy đi qua chuỗi và tham lam xây dựng thay thế trong quy trình. Tuy nhiên, nếu mẫu không phải là một chuỗi con, nó sẽ chạy trong thời gian O (2 n ) trong trường hợp xấu nhất. Điều này là do tại mọi vị trí mà mẫu và chuỗi có một ký tự trùng khớp, hàm sẽ tự kiểm tra xem mẫu đó có thực sự là một chuỗi hay không, và tìm ra nó không phải là lần thứ hai để thực sự tính kết quả.


2

JavaScript (ES6), 100 95 byte

(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

Đây là một hàm Lambda JavaScript hợp lệ. Đầu ra là hàm return. Đưa ra trong ba đối số ( a,b,c). Thêm vào f=lúc bắt đầu và gọi như thế 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")))


Chào mừng đến với PPCG! Các hàm không tên thường được chấp nhận , vì vậy bạn không cần f=trừ khi hàm của bạn được đệ quy, nhưng nó không giống như vậy.
Martin Ender

@ MartinBüttner Cảm ơn! :) Cập nhật câu trả lời của tôi.
Arjun

Thật không may, điều này sẽ thất bại nếu akhông chứa mẫu. Tôi cũng không chắc trả về một chuỗi các chuỗi có thể chấp nhận được.
Dennis

@Dennis Tôi đã cập nhật giải pháp của mình. Tôi nghĩ rằng nó chính xác bây giờ. Xin lỗi vì trả lời muộn và cập nhật. (Tôi chỉ nhận thấy bình luận của bạn, do đó sự chậm trễ)
Arjun

@MartinEnder Trong khi tôi đang trải qua tất cả các giải pháp của mình, tôi thấy rằng giải pháp này không chính xác. Nhưng, tôi đã sửa nó ngay bây giờ; và nó ngắn hơn năm byte (vì tôi đã để lại nhiều chỗ chơi golf không bị ảnh hưởng; lúc đó tôi là một tay golf mới làm quen, không phải là tôi là một người tuyệt vời: p). Xin lỗi vì đăng một giải pháp sai.
Arjun


1

Octave, 97 byte

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;

Lặp đi lặp lại sau đó để thay thế; tìm sự xuất hiện đầu tiên của ký tự đầu tiên, tìm ký tự tiếp theo trong chuỗi còn lại, lặp lại. Một điều thú vị của điều này là:

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

Vì ideone vẫn không chấp nhận các chức năng với các tên khác ngoài '', tôi sẽ chỉ để lại một mẫu chạy ở đây. Đầu vào chỉ được hiển thị cho một vài trường hợp thử nghiệm đầu tiên cho ngắn gọn. keylà đầu ra dự kiến, anslà đầu ra chức năng.

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

Những nhiệm vụ Octave ở những nơi không ngờ tới ( D(t=...)) khiến tôi bối rối :-)
Luis Mendo

1
@LuisMendo haha ​​... nó gần giống như ... một chồng! :)
cốc

1

Python 3, 123 byte

Một cách tiếp cận khác tôi muốn chia sẻ, đó là một vài byte ngắn hơn. Không có quy tắc chống lại thư viện / regex tiêu chuẩn, phải không?

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)

Tái bút Đây là sân golf đầu tiên của tôi. Hãy cho tôi biết bất kỳ vấn đề / cải tiến.


1

Bình thường, 22 byte

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

Xác minh tất cả các trường hợp thử nghiệm trong Trình biên dịch Pyth .

Lý lịch

Chúng tôi xây dựng một biểu thức chính từ mẫu bằng cách nối thêm $và đặt (.*?)giữa tất cả các ký tự. Regex này sẽ khớp với phần tiếp theo sẽ được thay thế và bất cứ thứ gì giữa các phần tử của nó và bất cứ thứ gì cho đến cuối chuỗi.

Vì các bộ lượng hóa là lười biếng, mỗi cái (.*?)sẽ khớp với càng ít ký tự càng tốt.

Đối với ma mẫu, regex được xây dựng là g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$.

Nếu mẫu phù hợp với đầu vào, nội dung r<str><regex>3 sẽ trả về một mảng chứa tiền tố (mọi thứ trước chuỗi sau), tất cả các nhóm được bắt (mọi thứ ở giữa và sau chuỗi sau) và postmatch (chuỗi trống).

Nếu mẫu không khớp, nội dung sẽ trả về một mảng đơn có chứa đầu vào ban đầu.

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

|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

Thạch , 23 byte

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

Đây là hai byte dài hơn câu trả lời Jelly khác của tôi , nhưng nó kết thúc ngay lập tức. Hãy thử trực tuyến!

xác minh

$ 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

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

⁴='-;ç\ñ⁴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 byte

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

Thử chi tiết tại đâ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

Julia, 93 90 86 byte

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

Phải kiểm tra riêng nếu trận đấu thành công sẽ phá hủy điểm số. Một sự thay thế sẽ đòi hỏi phải đúc Base.SubstitutionString, mà có lẽ không đáng ...

Chạy thử nghiệm

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

Julia, 62 59 58 byte

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

I / O ở dạng mảng ký tự.

xác minh

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 byte

Tôi vẫn thích nó ngắn hơn; có thể lưu 3 byte ( ""<) nếu Bđược đảm bảo không chứa 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;

lấy đối số từ dòng lệnh. Chạy với -r.

Thay thế các ký tự khi tìm thấy chúng;
in bản sao nếu tất cả các ký tự đã được thay thế; bản gốc khác.


1

Ruby, 70 64 59 58 byte

Chức năng ẩn danh. Đi qua chuỗi ađể xây dựng một chuỗi mới với các chữ cái được thay thế theo ký tự tiếp theo trong bc sau đó, nếu tất cả các ký tự trongb hết, hãy trả về chuỗi mới được tạo, nếu không trả về chuỗi gốc.

@histocrat đã giúp lưu 6 byte thông qua gsub .

Đã lưu 1 byte nhờ @Cyoce.

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

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


Bạn có thể lưu một byte bằng cách thay thế -1+i+=1bằng~-i+=1
Cyoce

0

Perl, 80 + 1 = 81 byte

Chạy với -pcờ

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

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

Mã theo thủ tục tạo ra một lệnh tìm kiếm và thay thế lệnh regex, sau đó nó sẽ thực thi trong bit mã cuối cùng.

Chuỗi ghosttrong ví dụ đầu tiên được chuyển thành chuỗi g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), có nghĩa là một gký tự được htheo sau bởi 0 hoặc nhiều ký tự, theo sau là 0 hoặc nhiều ký tự, theo sau là v.v.*? định lượng có nghĩa là tìm kiếm không tham lam và "ngấu nghiến" "Càng ít ký tự càng tốt, thay vì mặc định khớp càng nhiều càng tốt.

Chuỗi 12345sau đó được chuyển thành 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, được đánh giá sau khi biểu thức chính quy được thực hiện. Mỗi trong số đó $1,$2,$3,$4,$5thực sự là một phản hồi cho một nhóm bắt giữ (trong ngoặc đơn) từ chuỗi đầu tiên.


Tôi đề nghị mã này để lưu một vài byte : perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'. Tự mình đến với nó, nhưng nó khá gần với bạn, vì vậy tôi sẽ không đăng nó, đó sẽ là hai câu trả lời rất gần, nhưng hãy thoải mái chỉnh sửa của bạn!
Dada

Chỉ cần đi vào lúc này vì tôi thấy nó được liệt kê như một câu hỏi "liên quan" đến một vấn đề gần đây. Điều tốt nhất tôi nhận được là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 byte

#(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))

Một cơ bản reduce, không quá hài lòng về tất cả những dài first, restconjgọi hàm. Hy vọng để xem một cách tiếp cận tốt hơ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.