{"id":404,"date":"2025-03-10T23:52:21","date_gmt":"2025-03-11T02:52:21","guid":{"rendered":"https:\/\/www.wagnersalvi.com.br\/?p=404"},"modified":"2025-03-10T23:54:58","modified_gmt":"2025-03-11T02:54:58","slug":"explicando-o-algoritmo-de-burrows-wheeler-em-c-para-compressao-de-dados","status":"publish","type":"post","link":"http:\/\/www.wagnersalvi.com.br\/?p=404","title":{"rendered":"Explicando o Algoritmo de Burrows-Wheeler em C# usado em etapa anterior a Compress\u00e3o de Dados"},"content":{"rendered":"\n<p>O Algoritmo de Burrows-Wheeler (BWT) \u00e9 uma t\u00e9cnica de transforma\u00e7\u00e3o de dados, amplamente utilizada em compress\u00e3o de dados sem perda. Vamos analisar este algoritmo, explorando seu funcionamento, implementa\u00e7\u00e3o em C# e aplica\u00e7\u00f5es pr\u00e1ticas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">O que \u00e9 o Algoritmo de Burrows-Wheeler?<\/h2>\n\n\n\n<p>O BWT, desenvolvido por Michael Burrows e David Wheeler em 1994, \u00e9 uma transforma\u00e7\u00e3o revers\u00edvel de uma sequ\u00eancia de dados. Ele n\u00e3o comprime os dados diretamente, mas os reorganiza de uma maneira que torna a compress\u00e3o subsequente muito mais eficiente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Como funciona o BWT?<\/h2>\n\n\n\n<p>O algoritmo opera em quatro etapas principais:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cria\u00e7\u00e3o de rota\u00e7\u00f5es:<\/strong> Gera todas as rota\u00e7\u00f5es c\u00edclicas poss\u00edveis da string de entrada.<\/li>\n\n\n\n<li><strong>Ordena\u00e7\u00e3o:<\/strong> Ordena lexicograficamente estas rota\u00e7\u00f5es.<\/li>\n\n\n\n<li><strong>Extra\u00e7\u00e3o:<\/strong> Extrai a \u00faltima coluna da matriz de rota\u00e7\u00f5es ordenadas.<\/li>\n\n\n\n<li><strong>Adi\u00e7\u00e3o do \u00edndice:<\/strong> Adiciona o \u00edndice da string original na lista ordenada.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Implementa\u00e7\u00e3o em C#<\/h2>\n\n\n\n<p>Vamos implementar o BWT em C# passo a passo:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Linq;\nusing System.Text;\n\npublic class BurrowsWheeler\n{\n    public static string Transform(string s)\n    {\n        int n = s.Length;\n        var rotations = new string[n];\n\n        \/\/ Cria todas as rota\u00e7\u00f5es poss\u00edveis\n        for (int i = 0; i &lt; n; i++)\n        {\n            rotations[i] = s.Substring(i) + s.Substring(0, i);\n        }\n\n        \/\/ Ordena as rota\u00e7\u00f5es\n        Array.Sort(rotations);\n\n        \/\/ Extrai a \u00faltima coluna e encontra o \u00edndice da string original\n        var result = new StringBuilder();\n        int index = 0;\n        for (int i = 0; i &lt; n; i++)\n        {\n            result.Append(rotations[i][n - 1]);\n            if (rotations[i] == s) index = i;\n        }\n\n        \/\/ Adiciona o \u00edndice ao final da string transformada\n        return result.ToString() + \"$\" + index;\n    }\n\n    public static string InverseTransform(string transformed)\n    {\n        int dollarIndex = transformed.LastIndexOf('$');\n        string lastColumn = transformed.Substring(0, dollarIndex);\n        int originalIndex = int.Parse(transformed.Substring(dollarIndex + 1));\n\n        int n = lastColumn.Length;\n        var firstColumn = new string(lastColumn.OrderBy(c => c).ToArray());\n        \n        var next = new int[n];\n        for (int i = 0, j = 0; i &lt; n; i++)\n        {\n            char c = firstColumn[i];\n            next[i] = lastColumn.IndexOf(c, j);\n            j = next[i] + 1;\n        }\n\n        var result = new StringBuilder();\n        int current = originalIndex;\n        for (int i = 0; i &lt; n; i++)\n        {\n            result.Append(firstColumn[current]);\n            current = next[current];\n        }\n\n        return result.ToString();\n    }\n}<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Explica\u00e7\u00e3o Detalhada<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">Transforma\u00e7\u00e3o<\/h4>\n\n\n\n<p><strong>Cria\u00e7\u00e3o de rota\u00e7\u00f5es:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Geramos todas as rota\u00e7\u00f5es c\u00edclicas poss\u00edveis da string de entrada.<\/li>\n\n\n\n<li>Por exemplo, para &#8220;banana&#8221;, criamos: &#8220;banana&#8221;, &#8220;ananab&#8221;, &#8220;nanaba&#8221;, &#8220;anaban&#8221;, &#8220;nabana&#8221;, &#8220;abanan&#8221;.<\/li>\n<\/ul>\n\n\n\n<p><strong>Ordena\u00e7\u00e3o:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ordenamos estas rota\u00e7\u00f5es lexicograficamente.<\/li>\n\n\n\n<li>Resultado: &#8220;abanan&#8221;, &#8220;anaban&#8221;, &#8220;ananab&#8221;, &#8220;banana&#8221;, &#8220;nabana&#8221;, &#8220;nanaba&#8221;.<\/li>\n<\/ul>\n\n\n\n<p><strong>Extra\u00e7\u00e3o:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extra\u00edmos a \u00faltima coluna desta matriz ordenada.<\/li>\n\n\n\n<li>Neste caso: &#8220;nnbaa$a&#8221;.<\/li>\n<\/ul>\n\n\n\n<p><strong>Adi\u00e7\u00e3o do \u00edndice:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Adicionamos o \u00edndice da string original na lista ordenada (neste caso, 3).<\/li>\n\n\n\n<li>Resultado final: &#8220;nnbaa$a$3&#8221;.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Transforma\u00e7\u00e3o Inversa<\/h4>\n\n\n\n<p><strong>Separa\u00e7\u00e3o:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Separamos a \u00faltima coluna e o \u00edndice.<\/li>\n<\/ul>\n\n\n\n<p><strong>Reconstru\u00e7\u00e3o:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Usando a \u00faltima coluna, reconstru\u00edmos a primeira coluna ordenando os caracteres.<\/li>\n\n\n\n<li>Criamos um mapeamento entre as duas colunas.<\/li>\n\n\n\n<li>Come\u00e7ando pelo \u00edndice original, reconstru\u00edmos a string original.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Complexidade e Efici\u00eancia<\/h2>\n\n\n\n<p>Complexidade de tempo: O(n log n), principalmente devido \u00e0 etapa de ordena\u00e7\u00e3o.<br>Complexidade de espa\u00e7o: O(n), pois armazenamos todas as rota\u00e7\u00f5es.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Aplica\u00e7\u00f5es Pr\u00e1ticas<\/h2>\n\n\n\n<p>O BWT \u00e9 amplamente utilizado em:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Compress\u00e3o de dados:<\/strong> \u00c9 a base do algoritmo bzip2.<\/li>\n\n\n\n<li><strong>Bioinform\u00e1tica:<\/strong> \u00datil para compress\u00e3o e an\u00e1lise de sequ\u00eancias de DNA.<\/li>\n\n\n\n<li><strong>Processamento de texto:<\/strong> Facilita buscas eficientes em grandes volumes de texto.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Conclus\u00e3o<\/h2>\n\n\n\n<p>O Algoritmo de Burrows-Wheeler \u00e9 uma ferramenta poderosa no arsenal de qualquer desenvolvedor que trabalha com compress\u00e3o de dados ou processamento de texto. Sua capacidade de reorganizar dados de forma a facilitar a compress\u00e3o subsequente o torna inigualavel em muitas aplica\u00e7\u00f5es.<\/p>\n\n\n\n<p>Ao implementar e entender o BWT, voc\u00ea n\u00e3o apenas melhora suas habilidades de programa\u00e7\u00e3o, mas tamb\u00e9m ganha insights valiosos sobre t\u00e9cnicas avan\u00e7adas de manipula\u00e7\u00e3o de dados. <\/p>\n\n\n\n<p>Experimente com diferentes tipos de entrada e veja como o algoritmo se comporta &#8211; voc\u00ea ficar\u00e1 surpreso com sua efic\u00e1cia em diversos cen\u00e1rios!<\/p>\n<p>Views: 0<\/p>","protected":false},"excerpt":{"rendered":"<p>O Algoritmo de Burrows-Wheeler (BWT) \u00e9 uma t\u00e9cnica de transforma\u00e7\u00e3o de dados, amplamente utilizada em compress\u00e3o de dados sem perda. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":405,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[49],"tags":[206,43],"class_list":["post-404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacao","tag-burrows-wheeler","tag-programacao"],"_links":{"self":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts\/404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=404"}],"version-history":[{"count":0,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts\/404\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/media\/405"}],"wp:attachment":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=404"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}