Diberikan daftar string s_0, s_1, ..., s_n
menemukan string terpendek S
yang berisi masing-masing s_0, s_1, ..., s_n
sebagai substring .
Contoh :
S('LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE')='SEDOLOREMAGNAD'
S('ABCDE', 'BCD', 'C')='ABCDE'
Tulis program terpendek (atau fungsi) yang memecahkan masalah ini. Anda dapat mewakili string sebagai array atau daftar karakter / bilangan bulat jika Anda mau. Perpustakaan standar OK. Untuk input / output, Anda dapat menggunakan apa pun yang lebih nyaman: STDIN / STDOUT, prompt pengguna, nilai parameter / pengembalian fungsi dll.
Kinerja tidak kritis - katakanlah, untuk input dengan panjang total <100 karakter, hasilnya harus dihitung dalam <10 detik pada perangkat keras modern rata-rata.
Jawaban:
Python 2,
170153/157/159Dipersingkat berkat beberapa ide Baptiste .
Istirahat baris kedua tidak diperlukan.
Input:
'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'
Keluaran:
SEDOLOREMAGNAD
Bahkan dengan string input panjang, ini berjalan dalam waktu kurang dari 2 detik jika ada paling banyak 7 string input (seperti halnya dalam contoh yang diberikan, yang berjalan dalam
1,71,5 detik pada mesin saya). Dengan 8 atau lebih input string, bagaimanapun, dibutuhkan lebih dari 10 detik, karena kompleksitas waktuO(n!)
.Seperti yang ditunjukkan Baptiste,
range(99)
perlu diganti denganrange(len(w))
jika panjang input yang sewenang-wenang harus didukung (membuat total panjang kode 157 karakter). Jika string input kosong harus didukung, itu harus diubah menjadirange(len(w)+1)
. Saya pikirrange(99)
bekerja dengan benar untuk setiap panjang input total kurang dari 200.Tes lebih lanjut:
sumber
Mathematica
337 418372Setelah gagal mencoba menerapkan menggunakan Mathematica
LongestCommonSubsequencePositions
, saya beralih ke pencocokan pola.Aturan pencocokan pola,
mengambil pasangan kata yang diurutkan (diwakili sebagai daftar karakter) dan mengembalikan: (1) kata-kata,
{a,y}
dan{y,b}
diikuti oleh (2) substring yang umumy
,, yang menghubungkan akhir satu kata dengan awal kata lain, dan, akhirnya, kata gabungan{a,y,b}
itu akan menggantikan kata input. Lihat Belisarius untuk contoh terkait: /mathematica/6144/looking-for-longest-common-substring-sutionTiga karakter garis bawah berturut-turut menandakan bahwa elemen tersebut adalah urutan dari nol atau lebih karakter.
Reverse
digunakan kemudian untuk memastikan bahwa kedua pesanan diuji. Pasangan-pasangan yang berbagi surat-surat yang dapat ditautkan dikembalikan tidak berubah dan diabaikan.Edit :
Berikut ini menghapus dari daftar kata-kata yang "dikubur" (yaitu sepenuhnya terkandung) dengan kata lain, (sebagai tanggapan terhadap komentar @ flornquake).
Contoh :
kembali
Pemakaian
sumber
"LOREM", "ORE", "R"
?"LOREM"
?)GolfScript, 66 karakter
Cukup singkat, tetapi karena kompleksitas waktu yang eksponensial (dan GolfScript) benar-benar lambat, itu melanggar batas waktu 10 detik.
Contoh:
sumber
Python 2,
203187200Input:
['LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE']
Keluaran:
SEDOLOREMAGNAD
Edit
Menggunakan
reduce
dan beberapa tipuan impor kotor, saya dapat mengurangi ini lebih jauh (dan hanya untuk satu baris!):Edit 2
Seperti dicatat flornquake, ini memberikan hasil yang salah ketika satu kata terkandung dalam yang lain. Perbaikan untuk ini menambahkan 13 karakter lain:
Inilah versi yang dibersihkan:
Dimungkinkan untuk mengurangi beberapa karakter dengan mengorbankan kebenaran teoretis dengan menggunakan
range(99)
alih-alihrange(len(x))
(kredit kepada korban karena memikirkan yang satu ini).sumber
'LOREM', 'ORE', 'R'
salah menghasilkan outputLOREMORER
.Python, 144 karakter
S
Dibutuhkan satu set kataA
yang masih membutuhkan penempatan dan strings
berisi kata-kata yang ditempatkan sejauh ini. Kami memilih kata yang tersisaa
dariA
dan tumpang tindih dari0
kelen(a)
karakter dengan akhirs
.Hanya memakan waktu sekitar 0,15 detik pada contoh yang diberikan.
sumber
['LOREM', 'ORE', 'R']
. Saya telah mengambil kebebasan untuk memperbaikinya dan golf solusi Anda lagi:S=lambda A,s='':A and min((S(A-{a},(s+a[max(i*(s[-i:]==a[:i])for i in range(len(a))):],s)[a in s])for a in A),key=len)or s
(baris kedua tidak diperlukan). Penggunaan:S({'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'})
pengembalian'SEDOLOREMAGNAD'
.Haskell, 121
Kurang dua jika fungsi tidak perlu terikat pada nama
sumber