Halo teman-teman, apa kabar? Kali ini saya ingin membahas sedikit tentang salah satu problem yang ada di web rosalind.info. Judulnya ialah "Genome Assembly as Shortest Superstring". Sebagai acuan, teman-teman bisa cek dahulu problem yang akan kita bahas (disini).
Fragment assembly: menyusun kembali DNA yang terpisah.
Overview
Di problem ini kita akan disajikan bebarapa string (sebut saja array string S[]) dalam format FASTA. Tugas kita ialah mencari superstring dari string-string S[]. Superstring ialah, analoginya, jika kumpulan substring bersatu menjadi string, maka kumpulan string bersatu menjadi superstring.
Ide dari penyelesaiannya ialah, pertama, mengurutkan string-string S[] berdasarkan prefix dan suffix-nya. Setelah urut, hapus bagian yang overlapping dari string S[] untuk mencegah double writing.
Kode Pengerjaan
Berikut kode pengerjaannya dalam bahasa java :
- static class Data {
- int ances = -1;
- int success = -1;
- int diambil = 0;
- String strand;
- Data (String s) {
- this.strand = s;
- }
- }
- static void dirajang (Vector<Data> vStrand, Map<String, Vector<Integer>> cekPrev, Map<String, Vector<Integer>> cekSuff, int giliran) {
- String s = vStrand.lastElement().strand;
- int n = s.length();
- String prev = "";
- String suff = "";
- int diambil = 1;
- for (int i = 0; i < n / 2; i++) {
- prev += s.charAt(i);
- suff = s.charAt(n - 1 - i) + suff;
- }
- for (int i = n / 2; i < n; i++) {
- if (cekSuff.containsKey(prev += s.charAt(i))) {
- int cekSuffInt = cekSuff.get(prev).get(0);
- vStrand.lastElement().ances = cekSuffInt;
- vStrand.get(cekSuffInt).success = giliran;
- vStrand.lastElement().diambil = i + 1;
- cekSuff.get(prev).remove(0);
- }
- if (cekPrev.containsKey(suff = s.charAt(n - 1 - i) + suff)) {
- int cekPrevInt = cekPrev.get(suff).get(0);
- vStrand.lastElement().success = cekPrevInt;
- vStrand.get(cekPrevInt).ances = giliran;
- vStrand.get(cekPrevInt).diambil = i + 1;
- cekPrev.get(suff).remove(0);
- }
- if (!cekPrev.containsKey(prev)) cekPrev.put(prev, new Vector<>());
- cekPrev.get(prev).add(giliran);
- if (!cekSuff.containsKey(suff)) cekSuff.put(suff, new Vector<>());
- cekSuff.get(suff).add(giliran);
- diambil++;
- }
- }
- static void slashAndPrint (Data data) {
- for (int i = data.diambil; i < data.strand.length(); i++) {
- out.print(data.strand.charAt(i));
- }
- }
- static void solve() {
- Scanner sc = new Scanner(System.in);
- Map<String, Vector<Integer>> cekPrev = new HashMap<>();
- Map<String, Vector<Integer>> cekSuff = new HashMap<>();
- Vector<Data> vStrand = new Vector<>();
- int giliran = 0;
- sc.next();
- while (sc.hasNext()) {
- String s = "";
- while (sc.hasNext()) {
- String masuk = sc.next();
- if (masuk.charAt(0) == '>') break;
- s += masuk;
- }
- vStrand.add(new Data(s));
- dirajang(vStrand, cekPrev, cekSuff, giliran);
- giliran++;
- }
- for (int i = 0; i < vStrand.size(); i++) {
- if (vStrand.get(i).ances == -1) {
- int pvt = i;
- do {
- slashAndPrint(vStrand.get(pvt));
- pvt = vStrand.get(pvt).success;
- } while (pvt != -1);
- }
- }
- }
Penjelasan Kode
Kita mulai dari baris 47 (static void solve()). Pertama, kita masukkan dahulu string S[] (baris 54-64). Sembari memasukkan string, kita bisa sekalian mencari prefix dan suffix mana yang cocok dan bisa digabungkan (baris 62).
Di fungsi static void dirajang() (baris 10-41) saya memberi tanda urutan (1, 2, 3, ...) pada string-string S[]. Angka tersebut berfungsi sebagai penanda urutan sewaktu men-print jawabannya.
Langkah terakhir ialah men-print jawaban. Susun string-string S[] berdasarkan penanda urutan. Gabungkan semua menjadi 1 superstring. Dalam men-print jawaban, jangan lupa menghapus bagian-bagian DNA yang overlapping atau bertumpukan pada superstring.
Input dan Output
Seperti yang teman-teman lihat; disini, saya memakai fungsi next() (baris 57) untuk meng-input data string. Saya menggunakan hasNext() (baris 56) dikarenakan fungsi tersebut mampu meng-input data yang tidak diketahui jumlahnya. Fungsi tersebut sangat cocok jika dipakai untuk menangani input dengan format FASTA.
Sedangkan untuk output-nya saya memakai fungsi out.print() (baris 44). Fungsi tersebut adalah modifikasi dari fungsi System.out.print() yang merupakan fungsi default di java. Untuk lebih jelasnya, teman-teman bisa melihat kode tambahan untuk memodifikasi fungsi tersebut (input maupun output) di versi lengkap kode saya di github.
Sekian dari saya. Jika teman-teman ingin menanyakan sesuatu, teman-teman bisa menulisnya di kolom komentar. Semoga bermanfaat dan sampai jumpa di artikel berikutnya!
Referensi :
Sumber gambar 1: https://www.facebook.com/ProjectRosalind/
Sumber gambar 2: https://www.researchgate.net/figure/DNA-assemblyDNA-assembly-1st-step-The-DNA-is-purified-and-extracted-2nd-step-DNA-is_fig9_252323690
No comments:
Post a Comment