Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.87 KB | None | 0 0
  1. Úkolem je realizovat část programu (funkci), která umožní analyzovat strukturu genomu a vyhledávat v něm shodné úseky.
  2.  
  3. V tomto domácím úkolu nebudete implementovat celý program. Budete implementovat pouze jeho část -- jednu funkci se zadaným rozhraním. Funkce má specifikované vstupní parametry a způsob chování. Bude testována tak, že bude vložena do testovacího prostředí (námi vytvořeného programu), odkud bude volaná. Podle návratových hodnot funkce bude vyhodnoceno, zda Vaše implementace funkce je správná.
  4.  
  5. Konkrétně je Vaším úkolem implementovat funkci, která bude vyhledávat nejdelší společný podřetězec. Vstupem funkce jsou dva řetězce (zde konkrétně dva DNA řetězce, které např. kódují části genomu různých živých organismů). Úkolem funkce je nalézt v těchto řetězcích nejdelší společný úsek a ten vrátit jako nalezený nejdelší společný podřetězec. Pokud existuje více různých společných podřetězců stejné délky, pak je funkce vrátí všechny. Příklady:
  6. s1                s2                nejdelší společný podřetězec (podřetězce)
  7. ATTTCG            GTTCCA            TTC
  8. ATTTATTTA         GTTTCTTTG         TTT
  9. ATTTGTTTA         GTTTATTTG         GTTTA, ATTTG
  10.  
  11. Požadovaná funkce má rozhraní:
  12. char ** LCS ( char * s1, char * s2 );
  13. s1 a s2 jsou ASCII řetězce (ukazatele na jejich počátek), ve standardní C konvenci (binární nulou ukončené). Řetězce se mohou skládat pouze ze čtyř znaků: A, T, C a G.
  14. Návratová hodnota je dynamicky alokované pole obsahující všechny různé nalezené nejdelší společné podřetězce. Pokud mají vstupní řetězce více společných podřetězců stejné maximální délky, pak budou do výstupu uložené všechny (řetězce GTTTA a ATTTG z ukázky). Naopak, pokud se ten samý společný podřetězec vyskytne vícekrát, je uložen pouze jednou (řetězec TTT v ukázce). Funkce zajistí, že v poli za posledním nalezeným společným podřetězcem bude uložena hodnota NULL. Pořadí řetězců v poli není důležité.
  15. Pokud řetězce nemají žádný společný podřetězec (přesněji - pokud nejdelší společný podřetězec má délku 0 znaků), pak funkce nealokuje pole řetězců, ale rovnou vrátí NULL.
  16. Pokud je na vstupu neplatný řetězec (obsahuje jiné znaky než A, T, C, nebo G), pak funkce rovněž vrátí hodnotu NULL.
  17. Funkce musí návratovou hodnotu alokovat dynamicky. Alokovat je potřeba jednak vracené pole ukazatelů na řetězce a dále i paměť pro uložení vlastních řetězců. Alokaci proveďte funkcí malloc. Testovací prostředí si uložené hodnoty přečte, zkontroluje a paměť uvolní (jednak každý řetězec v poli a nakonec i pole ukazatelů). Za uvolnění ostatních paměťových bloků (které používáte v průběhu výpočtu funkce LCS) jste zodpovědní Vy.
  18.  
  19. Vaše implementace bude testovaná v prostředí s omezenou velikostí paměti a s limitem na dobu běhu. Limity jsou nastaveny tak, že naivní algoritmus (viz níže) uspěje v základních testech, ale ne již v testech bonusových. První bonus lze získat za rychlejší algoritmus založený na principu dynamického programování (viz níže). Druhý bonus lze získat za zrychlený algoritmus, který navíc bude minimalizovat své paměťové nároky.
  20.  
  21. Odevzdávejte soubor se zdrojovým kódem, který obsahuje Vaši funkci LCS a případně další Vaše podpůrné funkce, které z funkce LCS voláte. Do souboru nezačleňujte vkládání hlavičkových souborů, funkci main ani další nepotřebné funkce. Pokud je do souboru vložíte, riskujete, že se nepodaří program správně zkompilovat. Abyste nemuseli před odevzdáním opakovaně pracně vykopírovávat Vaší implementaci, využijte preprocesoru a makra __PROGTEST__:
  22. #ifndef __PROGTEST__
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. ...
  26. #endif /* __PROGTEST__ */
  27.  
  28. char ** LCS ( char * s1, char * s2 )
  29.  {
  30.    /* Vase implementace */
  31.  }
  32.  
  33. #ifndef __PROGTEST__
  34. int main ( int argc, char * argv [] )
  35.  {
  36.    /* testy Vasi implementace LCS () */
  37.    ...
  38.  }
  39. #endif /* __PROGTEST__ */
  40. Ukázka použití funkce:
  41.  
  42. /* res = LCS ( "ATAT", "TATA" );
  43.  *
  44.  * res[0] = "TAT"
  45.  * res[1] = "ATA"
  46.  * res[2] = NULL
  47.  */
  48.  
  49. /* res = LCS ( "AATCG", "CGGCGA" );
  50.  *
  51.  * res[0] = "CG"
  52.  * res[1] = NULL
  53.  */
  54.  
  55. /* res = LCS ( "AAAATCCGCGCGCCACGCT", "ACGCTCAAAATTTTTGCGCG" );
  56.  *
  57.  * res[0] = "ACGCT"
  58.  * res[1] = "AAAAT"
  59.  * res[2] = "GCGCG"
  60.  * res[3] = NULL
  61.  */
  62.  
  63. /* res = LCS ( "AAAAAATTTTTTTCCCCCCGGGGGGAAAAAA", "ATCGA" );
  64.  *
  65.  * res[0] = "AT"
  66.  * res[1] = "TC"
  67.  * res[2] = "CG"
  68.  * res[3] = "GA"
  69.  * res[4] = NULL
  70.  */
  71.  
  72. /* res = LCS ( "AAAAAAAAA", "TTTTTT" );
  73.  *
  74.  * res = NULL
  75.  */
  76.  
  77. /* res = LCS ( "AAA", "AAAA " );
  78.  *
  79.  * res = NULL
  80.  */
  81. Nápověda:
  82. Naivní algoritmus prostě zkusí pro všechny možné pozice v prvním a všechny možné pozice ve druhém řetězci porovnat, zda se na nich nenachází hledaný společný podřetězec. Pokud dojde ke shodě, určí jeho délku (a případně jej přidá k výstupu). V nejhorším případě provede kubický počet porovnání. Rozumná implementace naivního algoritmu uspěje v základních testech, neuspěje časově v testech bonusových.
  83. Vylepšená verze využívá 2D matici, do které si ukládá nalezené shody znaků. Provádí tedy kvadratický počet porovnání, má tedy šanci pracovat rychleji než naivní algoritmus. Popis algoritmu najdete např. na Wikipedii pod heslem "Longest common substring", podkapitola "dynamické programování".
  84. Vylepšený algoritmus projde prvním bonusovým testem, ale neprojde druhým. V základní implementaci má totiž velké paměťové nároky. Druhým bonusovým testem program projde pokud paměťové nároky snížíte. Neukládejte celou 2D matici, ale pouze relevantní části z ní. Inspiraci najdete na Wikipedii pod heslem "Longest common subsequence".
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement