{"id":20409669,"url":"https://github.com/sleekpanther/sequence-alignment","last_synced_at":"2026-03-10T15:31:49.305Z","repository":{"id":115108652,"uuid":"91747252","full_name":"SleekPanther/sequence-alignment","owner":"SleekPanther","description":"Sequence Alignment (Needleman–Wunsch Algorithm using Dynamic Programming) for aligning sequences (words, sentences, DNA etc.)","archived":false,"fork":false,"pushed_at":"2019-01-05T17:42:26.000Z","size":913,"stargazers_count":5,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-12T16:00:07.894Z","etag":null,"topics":["algorithm","algorithm-design","algorithms","dynamic","dynamic-programming","memo","memoization","memorization","needleman","needleman-wunsch","needlemanwunsch","noah","noah-patullo","optimal","optimal-substructure","optimality","patullo","patulo","pseudocode","wunsch"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SleekPanther.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-05-18T23:49:08.000Z","updated_at":"2022-11-27T09:32:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"21d31ebd-c3ed-4854-a454-830f05f8ea08","html_url":"https://github.com/SleekPanther/sequence-alignment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SleekPanther/sequence-alignment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fsequence-alignment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fsequence-alignment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fsequence-alignment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fsequence-alignment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SleekPanther","download_url":"https://codeload.github.com/SleekPanther/sequence-alignment/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fsequence-alignment/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30340117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:03:31.997Z","status":"ssl_error","status_checked_at":"2026-03-10T15:01:30.431Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithm","algorithm-design","algorithms","dynamic","dynamic-programming","memo","memoization","memorization","needleman","needleman-wunsch","needlemanwunsch","noah","noah-patullo","optimal","optimal-substructure","optimality","patullo","patulo","pseudocode","wunsch"],"created_at":"2024-11-15T05:42:53.837Z","updated_at":"2026-03-10T15:31:49.297Z","avatar_url":"https://github.com/SleekPanther.png","language":"Java","readme":"# Sequence Alignment\nImplementation of the classic **Dynamic Programming** problem using the [Needleman–Wunsch algorithm](https://en.wikipedia.org/wiki/Needleman%E2%80%93Wunsch_algorithm) which requires quadratic space \u0026 time complexity.\n\n## Problem Statement \nGiven 2 sequences, find the minimum cost of aligning the 2 sequences (**case insensitive**).  \nGaps can be inserted to 1 sequence or the other, but incur a penalty.\n\n`2` = **Gap Penalty (δ)**  \nIf 2 characters are aligned with each other, there may be a **mismatch penalty (α\u003csub\u003ei j\u003c/sub\u003e)**\n - `0` = aligning identical letters\n - `1` = aligning a vowel with a vowel, or a consonant with a consonant\n - `3` = aligning a vowel with a consonant\n\n**Minimum cost =** sum of mismatch \u0026 gap penalties (the optimal alignment)\n\n## Optimal Substructure\n**There may be multiple optimal paths, but this only finds `1` of them**  \n![](images/optimal-substructure.png)\n\n## Runtime\n**O(M*N)**  \nStorage: also O(M*N)\n\n## Pseudocode\n![](images/pseudocode.png)\n\n## Usage\n### Requirements \u0026 Caveats\n- **Alphanumeric characters only** (all others including spaces are sanitized out)\n- **Case insensitive**\n- `_` (*Underscore character*) represents gaps but only when displaying results (it will be removed \u0026 ignored if it's present in a sequence)\n- View results in a fixed-width font for the 2 sequences to be lined up\n- `predecessorIndexes` is calculated when creating `memoTable` but not used to find the actual alignment, only to show where the values in `memoTable` came from\n  - For example: if `predecessorIndexes[4][4]` contains the array `[4, 3]`, it means the value of `memoTable[4][4]` (which is `6`) came from `memoTable[4][3]` (i.e. `case3`, a character in `seq2` was aligned with a gap so it came from the left)\n  - `predecessorIndexes[0][0]` contains the array `[-1, -1]` because the upper left corner has no predecessor\n\n### Setup\n- Provide 2 strings (edit `testSequences` 2D array) \u0026 run `calculateAndPrintOptimalAlignment()`\n- Optionally change the penalties by passing in arguments to the non-default constructor  \nCurrently `vowelVowelMismatchPenalty`, `consonantConsonantMismatchPenalty` \u0026 `numberNumberMismatchPenalty` are the same, but all are arbitrary\n\n### Example: aligning \"mean\" with \"name\"\n![](images/example-mean-name.png)\n\n## Code Notes\n- `seq1` \u0026 `seq2` have a leading space added (after sanitizing illegal \u0026 whitespace characters)  \nThis is so that `seq1.charAt(i)` \u0026 `seq2.charAt(j)` work in the loops \u0026 the string indexes match up  \nIt causes some adjustments for the array sizes. \n - `memoTable = new int[seq1.length()][seq2.length()]` uses the exact value of `length()` which includes the space\n - Loops like `for(int i=0; i \u003c seq1.length(); i++)` use `i \u003c seq1.length()` to not go out of bounds of the string indexes\n - In `findAlignment()`, `int i = seq1.length() - 1;` \u0026 `int j = seq2.length() - 1;` since the 2 sequences have leading spaces \u0026 arrays indexes start from `0`\n- `findAlignment()` retraces each calculation in the `memoTable` to see where it came from  \n\n## References\n- [String Alignment using Dynamic Programming - Gina M. Cannarozzi](http://www.biorecipes.com/DynProgBasic/code.html) to retrace the memo table \u0026 find the alignment\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fsequence-alignment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleekpanther%2Fsequence-alignment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fsequence-alignment/lists"}