Apakah ada struktur data 'string stack' yang mendukung operasi string ini?

28

Saya mencari struktur data yang menyimpan satu set string di atas set karakter , yang mampu melakukan operasi berikut. Kami menunjukkan D ( S ) sebagai struktur data menyimpan set string S .ΣD(S)S

  • Add-Prefix-Setpada : diberi beberapa set T dari string (mungkin kosong), yang ukurannya dibatasi oleh sebuah konstanta dan yang panjang stringnya dibatasi oleh sebuah konstanta, mengembalikan D ( { t s | t T , s S } ) . Kedua konstanta melompat-lompat ini bersifat global: mereka adalah sama untuk semua masukan T .D(S)TD({ts | tT,sS})T
  • Get-Prefixespada : return { a | a s S , a Σ } . Perhatikan bahwa saya tidak terlalu keberatan struktur apa yang digunakan untuk set ini, selama saya dapat menyebutkan isinya dalam waktu O ( | Σ | ) .D(S){a | asS,aΣ}O(|Σ|)
  • Remove-Prefixespada : return D ( { s | a s S , a Σ } ) .D(S)D({s | asS,aΣ})
  • Merge: diberikan dan D ( T ) , mengembalikan D ( S T ) .D(S)D(T)D(ST)

Sekarang, saya benar-benar ingin melakukan semua operasi ini di waktu, tapi aku baik-baik saja dengan struktur yang melakukan semua operasi ini di o ( n ) waktu, di mana n adalah panjang dari string terpanjang di struktur. Dalam kasus penggabungan, saya ingin waktu berjalan o ( n 1 + n 2 ) , di mana n 1 adalah n untuk yang pertama dan n 2 the n untuk struktur kedua.O(1)o(n)no(n1+n2)n1nn2n

Persyaratan tambahan adalah bahwa struktur tidak dapat diubah, atau setidaknya operasi di atas mengembalikan struktur 'baru' sehingga penunjuk ke yang lama masih berfungsi seperti sebelumnya.

Catatan tentang amortisasi: itu baik-baik saja, tetapi Anda harus waspada terhadap ketekunan. Ketika saya menggunakan kembali struktur lama sepanjang waktu, saya akan berada dalam masalah jika saya mengenai kasus terburuk dengan beberapa rangkaian operasi pada struktur yang sama (jadi abaikan struktur baru yang dibuatnya).

Saya ingin menggunakan struktur seperti itu dalam algoritma parsing yang sedang saya kerjakan; struktur di atas akan menampung lookahead yang saya butuhkan untuk algoritma.

Saya sudah mempertimbangkan menggunakan trie , tetapi masalah utamanya adalah saya tidak tahu cara menggabungkan percobaan secara efisien. Jika set string Add-Prefix-Sethanya terdiri dari string karakter tunggal, maka Anda dapat menyimpan set ini dalam tumpukan, yang akan memberi Anda waktu berjalan untuk tiga operasi pertama. Namun, pendekatan ini tidak berfungsi untuk menggabungkan keduanya.O(1)

Akhirnya, perhatikan bahwa saya tidak tertarik pada faktor : ini konstan untuk semua yang saya pedulikan.|Σ|

Alex ten Brink
sumber
Apakah string hanya dibangun oleh operasi Add-Prefix-Setatau Anda mulai dengan serangkaian string yang sewenang-wenang?
Joe
2
n1=n2STo(n1+n2)
Anda mulai dengan satu set dengan satu string char-tunggal di dalamnya, tetapi string kosong juga baik-baik saja (Anda bisa Add-Prefix-Setmelakukannya)
Alex ten Brink
@ Jo: itu pertanyaan yang bagus - Saya mulai yakin operasi penggabungan cukup banyak merusak peluang mendapatkan struktur seperti itu ...
Alex ten Brink
(n1,n2)

Jawaban:

5

Saya berpikir untuk beberapa waktu, tetapi tidak menemukan masalah dengan melakukan semua operasi Anda dengan cara yang paling bodoh dalam struktur DAG seperti trie:

Add-Awalan-Set

T

O(|T|)

Menggabungkan

Satukan akar dari dua struktur: buat semua anak simpul dari anak akar kedua dari simpul pertama. Sekarang Anda mungkin memiliki beberapa sisi yang ditandai dengan karakter yang sama dari node yang sama.

O(1)

Pembaruan malas root

  1. O(|Σ|)O(1)
  2. O(1)

Dapatkan-awalan

Malas memperbarui root. Sekarang temukan semua anak-anak dari root dan laporkan set surat di tepi pergi ke mereka.

O(|Σ|)

Hapus-awalan

Malas memperbarui root. Satukan semua anak dari root dan atur pointer root ke hasil unite ini. Malas memperbarui root baru.

O(|Σ|)

Kegigihan

O(1)O(|Σ|)O(logN)N

maksay
sumber