Thực hiện hoàn thành tab


31

Hoàn thành tab là một tính năng hữu ích tự động hoàn thành các lệnh được viết một phần. Bạn sẽ thực hiện nó.

Ví dụ, nếu các lệnh khả dụng là ['apply','apple','apple pie','eat'], thì asẽ hoàn thành appl, vì tất cả các lệnh bắt đầu acũng bắt đầu bằng appl.

Đầu ra đầu vào

Bạn cần nhập một chuỗi, A và một chuỗi các chuỗi, B.

Bạn cần xuất tiền tố chung dài nhất của tất cả B bắt đầu bằng A.

  • Nếu không có tùy chọn nào bắt đầu bằng A, thì trả về A
  • Bạn có thể giả sử rằng B là không trống và tất cả các chuỗi đều không trống
  • Bạn không thể cho rằng bất kỳ tùy chọn nào bắt đầu bằng A, cũng không phải là tiền tố chung sẽ dài hơn A
  • Bạn có thể nhạy cảm trường hợp hoặc trường hợp không nhạy cảm.
  • Bạn chỉ cần xử lý ASCII có thể in
  • Được xây dựng mà rõ ràng thực hiện nhiệm vụ này được cho phép

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

'a'       ['apply','apple','apple pie','eat'] => 'appl'
'a'       ['apple pie']                       => 'apple pie'
'apple'   ['eat','dine']                      => 'apple'
'program' ['programa','programb']             => 'program'
'*%a('    ['*%a()-T>','*%a()-T<','@Da^n&']    => '*%a()-T'
'a'       ['abs','absolute','answer']         => 'a'
'a'       ['a','abs']                         => 'a'
'one to'  ['one to one','one to many']        => 'one to '

Lưu ý không gian dấu trên trường hợp kiểm tra cuối cùng

Đây là một , vì vậy hãy đưa ra câu trả lời của bạn càng ngắn càng tốt!



Bạn có thể thêm một ví dụ với các ký tự ASCII không chữ, có thể in được cho hậu thế không?
Conor O'Brien

Nhiều ví dụ với các ký tự không phải là chữ cái không thể làm tổn thương. Tôi vừa xóa câu trả lời của mình vì tôi nhận ra rằng nó đã bị \​hỏng với đầu vào có chứa hoặc '.
Dennis

Không chắc chắn làm thế nào để đại diện 'trong một ví dụ. Nếu tôi sử dụng "cho các chuỗi, thì các chuỗi khác với các ví dụ khác.
Nathan Merrill

Đó chính xác là vấn đề mà câu trả lời của tôi có. : P
Dennis

Câu trả lời:


10

JavaScript (ES6), 75 byte

(s,a)=>/^(.*).*(\n\1.*)*$/.exec(a.filter(e=>e.startsWith(s)).join`
`)[1]||s

Giải thích: Các bộ lọc trên tất cả các tiền tố phù hợp, sau đó kết hợp với các dòng mới và khớp với một biểu thức chính tìm thấy tiền tố chung dài nhất trong tất cả các dòng. Nếu không có tiền tố thì regex trả về một chuỗi rỗng trong trường hợp đó chúng ta chỉ cần trả về chuỗi gốc.


Bạn có thể thay thế e.startsWith(s)bằng e.match("^"+s)một byte tắt Currying sẽ cứu người khác
Shaun H

@ShaunH Tôi không thể sử dụng matchvới ASCII có thể in tùy ý.
Neil

Oh phải regex và nhân vật điều khiển. bạn vẫn có thể cà ri (s,a)=>đếns=>a=>
Shaun H

7

Thạch , 14 12 byte

ḣJ$€ċÐff\ṪṪȯ

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

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

ḣJ$€ċÐff\ṪṪȯ  Main link. Left argument: B. Right argument: A

  $€          Convert the two links to the left into a monadic chain and apply it
              to each string s in B.
 J              Generate the indices of s, i.e., [1, ..., len(s)].
ḣ               Head; for each index i, take the first i characters of s.
              This generates the prefixes of all strings in B.
     Ðf       Filter; keep prefixes for which the link to the left returns 1.
   ċ            Count the number of times A appears in the prefixes of that string.
       f\     Do a cumulative (i.e., keeping all intermediate values) reduce by
              filter, keeping only common prefixes. f/ is a more obvious choice,
              but it errors on an empty array, i.e., when A isn't a prefix of any
              string in B.
         Ṫ    Tail; take the last prefix array (if any) or return 0.
          Ṫ   Tail; take the last common prefix (if any) or return 0.
           ȯ  Logical OR (flat); replace 0 with A, leave strings untouched.

6

Bình thường, 14 13 byte

Cảm ơn @isaacg cho -1 byte

.xe@F/#z._MQz

Một chương trình lấy danh sách các chuỗi, sau đó là chuỗi, trên STDIN và in kết quả.

Xác nhận tất cả các trường hợp kiểm tra

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

.xe@F/#z._MQz  Program. Inputs: Q, z
        ._MQ   Map prefixes over Q
     /#z       Filter that by count(z)>0, removing the prefixes corresponding to elements
               in Q that do not start with z
   @F          Fold intersection over that. This yields all the common prefixes
  e            Yield the last element of that, giving the longest common prefix, since the
               prefixes are already sorted by length
.x             But if that throws an exception since no elements of Q start with z:
            z  Yield z instead
               Implicitly print

1
f}zT=>/#z
isaacg

5

PowerShell v3 +, 112 byte

param($a,$b)if($c=@($b-like"$a*")){([char[]]$c[0]|%{($i+="$_")}|?{($c-like"$_*").count-eq$c.count})[-1]}else{$a}

Đưa đầu vào dưới dạng một chuỗi $avà một chuỗi các chuỗi $b. Sử dụng -liketoán tử để lấy ra các phần tử từ $bđó (không phân biệt chữ hoa chữ thường) bắt đầu bằng $a, bỏ rõ ràng các phần tử đó thành một mảng @(...)(vì kết quả có thể là một kết quả như một vô hướng, trong đó trường hợp lập chỉ mục sau đó thất bại) và lưu trữ mảng đó vào $c.

Điều đó tạo thành ifmệnh đề. Nếu không có gì trong $c(nghĩa là không có gì bắt đầu bằng $a, vì vậy mảng trống), sau đó xuất ra $avới else. Nếu không thì ...

Chúng tôi truyền phần tử đầu tiên $cdưới dạng char-array và lặp qua từng phần tử, nối chuỗi với phần trước $ivà đặt các chuỗi trên đường ống thông qua các parens đóng gói. Những thứ đó được lọc qua |?{...}( Where-Objectmệnh đề) để xác minh rằng .countof $c-eqthông thường .countcủa những thứ trong $cđó là -likechuỗi con (nghĩa là chuỗi con khớp với mọi thứ trong $ c). Vì chúng tôi đang xây dựng các chuỗi con của chúng theo thứ tự từ ngắn nhất đến dài nhất, chúng tôi cần chuỗi cuối cùng [-1].

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

PS C:\Tools\Scripts\golfing> $tests=@('a',@('apply','apple','apple pie','eat')),@('a',@('apple pie')),@('apple',@('eat','dine')),@('program',@('programa','programb')),@('one to',@('one to one','one to many')),@('*%a(',@('*%a()-T>', '*%a()-T<', '@Da^n&'))

PS C:\Tools\Scripts\golfing> $tests|%{""+$_[0]+" ("+($_[1]-join',')+") -> "+(.\implement-tab-completion.ps1 $_[0] $_[1])}
a (apply,apple,apple pie,eat) -> appl
a (apple pie) -> apple pie
apple (eat,dine) -> apple
program (programa,programb) -> program
one to (one to one,one to many) -> one to 
*%a( (*%a()-T>,*%a()-T<,@Da^n&) -> *%a()-T

4

Python 2, 122 byte

s=input();l=[x for x in input()if x[:len(s)]==s]or[s];i=len(l[0])
while len(l)>1:i-=1;l=set(x[:i]for x in l)
print l.pop()

Chương trình đầy đủ; lấy chuỗi và danh sách từ stdin chính xác như được đưa ra trong các ví dụ, ngoại trừ các đầu vào phải nằm trên các dòng riêng biệt.

Xác nhận tất cả các trường hợp kiểm tra


Tại sao l.pop()thay vì l[-1]?
Cyoce

@Cyoce Bởi vì lthường là settại thời điểm đó, không cho phép lập chỉ mục (không có thứ tự). (May mắn thay, cả bộ và danh sách đều hỗ trợ pop().)
DLosc

3

Perl, 54 byte

Bao gồm +2 cho -Xp(có thể kết hợp với -e) và +3 cho -i(không thể kết hợp)

Cung cấp từ điển về STDIN và từ sau -itùy chọn, ví dụ:

perl -ia -Xpe '/^\Q$^I\E.*?(?{$F[$a{$&}++]=$&})^/}{$_=pop@F||$^I'
apply
apple
apple pie
eat
^D

Chỉ cần mã:

/^\Q$^I\E.*?(?{$F[$a{$&}++]=$&})^/}{$_=pop@F||$^I

3

Perl, 61 byte

Bao gồm +2 cho -0p

Chạy với từ đầu tiên theo sau là các từ trong từ điển trên STDIN:

tabcompletion.pl
a
apply
apple
apple pie
eat
^D

tabcompletion.pl:

#!/usr/bin/perl -0p
/^(.+)
((?!\1).*
)*(\1.*).*
((?!\1).*
|\3.*
)*$|
/;$_=$3||$`

2

Python 2, 112 byte

lambda n,h:[a.pop()for a in[{s[:-i]for s in h if s.find(n)==0}for i in range(-len(`h`),0)]+[{n}]if len(a)==1][0]

2

Haskell, 67 byte

(a:b)?(c:d)|a==c=a:(b?d)
_?_=""
s%l=foldr1(?)$max[s][x|x<-l,x?s==s]

Hàm phụ trợ ?tìm tiền tố chung dài nhất của hai chuỗi bằng cách đệ quy ký tự đầu tiên miễn là nó giống nhau cho cả hai chuỗi và chuỗi không trống.

Các chức năng chính %đầu tiên giữ chỉ các dây trong danh sách bắt đầu bằng cho một s, kiểm tra bởi các tiền tố chung dài nhất với sbị s. Để xử lý không có cuộc thi hợp lệ, nó thêm svào một kết quả trống thông qua max. Sau đó, nó tìm thấy tiền tố phổ biến dài nhất trong số đó bằng cách gấp hàm nhị phân ?.


2

Python 2, 75 byte

import os
lambda s,x:os.path.commonprefix([t for t in x if s<=t<s+'ÿ'])or s

Cảm ơn @xnor đã gợi ý tích hợp, ban đầu được sử dụng bởi @BetaDecay trong câu trả lời này .

Đối với mục đích ghi điểm, ÿcó thể được thay thế bằng một byte DEL. Kiểm tra nó trên Ideone .


1

D, 88 byte

S f(S)(S p,S[]q){try p=q.filter!(a=>a.startsWith(p)).fold!commonPrefix;catch{}return p;}

Sử dụng:

assert(f("a", ["apply","apple","apple pie","eat"]) ==  "appl");

Mã chỉ đơn giản là loại bỏ tất cả các phần tử từ qđó không bắt đầu bằng p, sau đó tính toán phần tiếp theo ban đầu phổ biến lớn nhất của các phần tử còn lại.

Các tham số templated tiết kiệm cho chúng tôi hai lần lặp lại stringvà một trong số auto. Việc sử dụng sai ngoại lệ cho phép chúng ta tránh biến tạm thời và điều kiện có thể cần thiết để xử lý trường hợp không có yếu tố qbắt đầu p.


1

Python 2, 107 102 byte

s,x=input();r='';q=1
for c in zip(*[t for t in x if s<=t<s+'ÿ']):q/=len(set(c));r+=c[0]*q
print r or s

Đối với mục đích ghi điểm, ÿcó thể được thay thế bằng một byte DEL. Kiểm tra nó trên Ideone .

Cảm ơn @xnor vì đã tiết kiệm 5 byte!


Với os.path.commonprefix Beta Decay được tìm thấy , bạn có thể yêu cầu nó làm việc cho bạn.
xnor

Wow, tiết kiệm rất nhiều byte. Bạn có chắc chắn bạn không muốn đăng nó cho mình?
Dennis

Tôi sẽ không cảm thấy đúng khi đăng nó vì ý tưởng của Beta Decay kết hợp với câu trả lời của bạn.
xnor

Đối với giải pháp của bạn, nó có vẻ ngắn hơn một chút để lặp lại for c in ...trực tiếp và chấm dứt với lỗi sau khi in như thế nào if len(set(c))>1:print r or s;_.
xnor

Tôi nghĩ rằng sẽ thất bại nếu x là một mảng đơn.
Dennis

1

PHP, 167 160 157 152 byte

<?for($r=preg_grep("$^".preg_quote($s=$_GET[s])."$",$a=$_GET[a]);$r[0]>$s&&preg_grep("$^".preg_quote($t=$s.$r[0][strlen($s)])."$",$a)==$r;)$s=$t;echo$s;

Tôi có thể lưu thêm 3 byte bằng cách gán các biến với preg_greppreg_quote, nhưng eh.

phá vỡ

for(
    // find items in $a that start with $s
    $r=preg_grep("$^".preg_quote($s=$_GET[s])."$",$a=$_GET[a]);
    // while the first match is longer than $s
    $r[0]>$s
    // and appending the next character of the first match
    &&preg_grep("$^".preg_quote($t=$s.$r[0][strlen($s)])."$",$a)
    // does not change the matches
    ==$r
;)
    // keep appending
    $s=$t;
return$s;

1

PHP, 156 byte

với nhiều sự giúp đỡ từ Titus Cảm ơn bạn

<?foreach($_GET[t]as$v)if(strstr($v,$s=$_GET[s])==$v)$r[]=$z=$v;for(;$i++<strlen($z);){$s=substr($z,0,$i);foreach($r as$x)if($x[$i]!=$z[$i])break 2;}echo$s;

PHP, 199 byte

32 Byte tiết kiệm bằng Titus với mảng_unique

<?foreach($_GET[t]as$v)if(strstr($v,$s=$_GET[s])==$v)$r[]=$v;for(;$i++<strlen($r[0]);$a=[]){foreach($r as$x)$a[]=substr($x,0,$i);if(count($r)==count($a)&count(array_unique($a))<2)$s=$a[0];}echo$s;

Tôi biết rằng Giải pháp Regex của Titus ngắn hơn cho đến khi Titus giúp tôi cải thiện con đường của mình. Có lẽ cách tôi tìm thấy là thú vị cho bạn


1
1) Thay thế $zbằng $sđể sửa chữa apple, [eat,dine]trường hợp. 2) $l=đã lỗi thời; Bạn không nên sử dụng biến đó. (-2) 3) $i++<$mngắn hơn ++$i<=$m. (-1) 4) substr($x,0,$i);ngắn hơn str_split($x,$i)[0]. (-3) 5) Bạn có thể đặt $r[]=$vbên trong strlen. (-5)
Tít

1
6) <2ngắn hơn ==1. (-1) 7) Bạn có thể sử dụng strstrtrong vòng lặp đầu tiên : strstr($v,$s)==$v. (-3)
Tít

1
Hãy để tôi viết lại nó: 5) Bạn có thể kết hợp $r[]=$v;$m=max($m,strlen($v));để $m=max($m,strlen($r[]=$v));thả các lọn tóc. Điều này không chạm vào điều kiện.
Tít

1
Suy nghĩ thứ hai, bạn không cần $mchút gì cả. Tất cả những gì bạn cần là một cái gì đó> = chiều dài tối thiểu của sự thay thế. 5 mới) Thay thế {$r[]=$v;$m=max($m,strlen($v));}bằng $r[]=$v;}<$mbằng <strlen($r[0])(-13)
Tít

1
Tuyệt quá! Và tôi vừa tìm thấy một gôn khác: 9) $r[]=$z=$v;trong vòng đầu tiên và {$s=substr($z,0,$i);foreach($r as$x)if($x[$i]!=$z[$i])break 2;}cho lần thứ hai (-3)
Tít

1

Võng mạc, 60 byte

^(.*)(\n(?!\1).*)*(\n(\1.*)).*(\n((?!\1)|\4).*)*$
$4
s`\n.*

Các dòng mới trailing là đáng kể. Lấy đầu vào là chuỗi trên một dòng và sau đó mỗi từ trên một dòng riêng biệt (nhưng không có dòng mới nào!). Hoạt động theo cách tương tự với câu trả lời JavaScript của tôi bằng cách khớp với tiền tố chung dài nhất của tất cả các dòng bắt đầu bằng chuỗi trên dòng đầu tiên. Nếu nó không tìm thấy thì nó chỉ cần xóa tất cả các từ.


0

Scala, 119 byte

def f(s:String,a:Seq[Char]*)=a filter(_ startsWith s)reduceOption(_ zip _ takeWhile(t=>t._1==t._2)map(_._1))getOrElse s

Ung dung:

def tabComplete(input: String, options: Seq[Char]*) = {
  options.
  filter((x: String) => x.startsWith(input)).
  reduceOption((x: Seq[Char], y: Seq[Char]) =>
    x.zip(y).
    takeWhile((t: (Char, Char)) => t._1 == t._2).
    map((t: (Char, Char)) => t._1)
  ).getOrElse(input)
}

Giải trình:

def g(s:String,a:Seq[Char]*)= //define a method g with a string and a vararg array of strings as parameter
  a filter(_ startsWith s)    //filter the options to contains only elements starting with the input
  reduceOption(               //if the filtered array is nonempty, reduce it: 
    _ zip _                     //zip two elements together
    takeWhile(t=>t._1==t._2)    //take the tuples while they contain the same char
    map(_._1)                   //take the first element from each tuple
  )getOrElse s                //else return the input


0

05AB1E , 14 byte

ʒIÅ?}€ηøʒË}‚˜θ

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

ʒ   }           # Filter the (implicit) input-list
 IÅ?            #  Does it start with the (second) input-string
                #   i.e. ["codex","bla","codegolf"] and "c" → ["codex","codegolf"]
     €η         # Then take the prefixes of every remaining string
                #  → [["c","co","cod","code","codex"],
                #     ["c","co","cod","code","codeg","codego","codegol","codegolf"]]
       ø        # Zip/transpose; swapping rows/columns
                #  → [["c","c"],["co","co"],["cod","cod"],["code","code"],["codex","codeg"]]
        ʒ }     # Filter:
         Ë      #  Only keep sublists which only contain the same substrings
                #   → [["c","c"],["co","co"],["cod","cod"],["code","code"]]
               # Pair it with the (second implicit) input
                #  → ["c",["c","c"],["co","co"],["cod","cod"],["code","code"]]
                # (workaround if nothing in the input-list starts with the input-string)
            ˜   # Flatten this list
                #  → ["c","c","c","co","co","cod","cod","code","code"]
             θ  # And only leave the last item (which is output implicitly as result)
                #  → "code"

0

Gaia , 12 byte

e…¦&⊢…Ė⁇_+ₔ)

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

Lấy đầu vào là B, sau đó A.

e		| eval B as list of strings
 …¦		| take prefixes of each string
   &⊢		| reduce by set intersection
     …		| take list prefixes of each.
      Ė⁇	| Keep only those with A as an element
	_	| flatten
	 +ₔ	| add A to the beginning of the list
	   )	| take the last element
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.