{"id":1346,"date":"2022-07-05T08:48:48","date_gmt":"2022-07-05T11:48:48","guid":{"rendered":"http:\/\/www.galirows.com.br\/meublog\/programacao\/?p=1346"},"modified":"2022-07-05T09:02:03","modified_gmt":"2022-07-05T12:02:03","slug":"troca-valor-variaveis-exercicios-simples-possuem-muitas-formas-diferentes-de-resolver","status":"publish","type":"post","link":"http:\/\/www.galirows.com.br\/meublog\/programacao\/troca-valor-variaveis-exercicios-simples-possuem-muitas-formas-diferentes-de-resolver\/","title":{"rendered":"Troca de valor entre vari\u00e1veis: mesmo exerc\u00edcios simples possuem muitas formas diferentes de resolver"},"content":{"rendered":"\n<p>Escrevo para apresentar a solu\u00e7\u00f5es algor\u00edtmicas para um problema apresentam uma grande varia\u00e7\u00e3o. Logicamente os problemas mais simples possuem menor quantidade poss\u00edvel de varia\u00e7\u00e3o, mas trago aqui um exerc\u00edcio tradicional introdut\u00f3rio de programa\u00e7\u00e3o para discutir essa quest\u00e3o.<\/p>\n\n\n\n<p>Enunciado: elabore um algoritmo que, dado dois valores, troque o conte\u00fado de um pelo do outro.<\/p>\n\n\n\n<p>Acredito que a primeira tentativa dos iniciantes com programa\u00e7\u00e3o seja similar a que mostro a seguir. Nela, simplesmente \u00e9 feita a atribui\u00e7\u00e3o de <em>x em y<\/em> e de <em>y em x<\/em>. Olhando o resultado \u00e9 poss\u00edvel verificar que a solu\u00e7\u00e3o n\u00e3o funciona (o resultado da execu\u00e7\u00e3o mostra: <em><strong>x=5 e y=5<\/strong><\/em>). Isso porque, na atribui\u00e7\u00e3o feita na linha 5, o valor de <em>x<\/em> \u00e9 perdido pois ele \u00e9 sobrescrito com o valor de <em>y<\/em>. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">#include &lt;stdio.h&gt;\nint main() {\n    int x=1, y=5;\n\n    x = y; \/\/x recebe 5\n    y = x; \/\/y recebe 5, pois x recebeu 5 antes\n\n    printf(\"x=%i e y=%i\", x, y);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>A forma mais comum de resolver esse problema envolve definir uma vari\u00e1vel auxiliar que armazena o valor de <em>x <\/em>antes dele ser sobrescrito e depois utiliza o valor armazenado dessa vari\u00e1vel. O resultado dessa solu\u00e7\u00e3o \u00e9 mostrado no c\u00f3digo a seguir.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include &lt;stdio.h&gt;\nint main() {\n    int x=1, y=5, aux;\n\n    aux = x; \/\/aux recebe 1\n    x = y;   \/\/x recebe 5\n    y = aux; \/\/y recebe 1\n\n    printf(\"x=%i e y=%i\", x, y);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>Uma melhoria, pelo menos considerando que ela economiza a vari\u00e1vel tempor\u00e1ria \u00e9 mostrada a seguir.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include &lt;stdio.h&gt;\nint main() {\n    int x=1, y=5;\n \n    x = x + y; \/\/ x recebe 1+5 = 6\n    y = x - y; \/\/ y recebe 6-5 = 1\n    x = x - y; \/\/ x recebe 6-1 = 5\n \n    printf(\"x=%i e y=%i\", x, y);\n \n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>Embora as duas solu\u00e7\u00f5es apresentas possuam a mesma complexidade de tempo (a complexidade delas \u00e9 O(1)), a segunda solu\u00e7\u00e3o n\u00e3o exige qualquer vari\u00e1vel adicional para a troca.<\/p>\n\n\n\n<p>As opera\u00e7\u00f5es aritm\u00e9ticas utilizadas (soma e subtra\u00e7\u00e3o) poderiam ser substitu\u00eddas por multiplica\u00e7\u00e3o e divis\u00e3o, conforme mostrado a seguir. Essa op\u00e7\u00e3o n\u00e3o altera a complexidade da solu\u00e7\u00e3o, apenas aplica outros c\u00e1lculos e mostra outra forma de aplicar o mesmo princ\u00edpio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">    x = x * y; \/\/ x recebe 1*5 = 5\n    y = x \/ y; \/\/ y recebe 5\/5 = 1\n    x = x \/ y; \/\/ x recebe 5\/1 = 5<\/code><\/pre>\n\n\n\n<p>A solu\u00e7\u00e3o utilizando multiplica\u00e7\u00e3o e divis\u00e3o, embora tenha o mesmo desempenho da op\u00e7\u00e3o com soma e subtra\u00e7\u00e3o, n\u00e3o recomendo a utiliza\u00e7\u00e3o. Veja que ela apresenta problema se o valor de <em>y<\/em> for zero (geraria uma divis\u00e3o por zero, o que n\u00e3o \u00e9 permitido). Sendo assim, \u00e9 mais seguro utilizar a op\u00e7\u00e3o com soma e subtra\u00e7\u00e3o.<\/p>\n\n\n\n<p>Uma outra solu\u00e7\u00e3o envolve o uso de um operador <em>bitwise<\/em>, no caso, o <em>bitwise XOR<\/em> (veja mais sobre os operadores <em>bitwise<\/em> em <a href=\"http:\/\/www.galirows.com.br\/meublog\/programacao\/operadores-bitwise-cpp\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.galirows.com.br\/meublog\/programacao\/operadores-bitwise-cpp\/<\/a>). Com esse operador, o par de bits comparados precisa que apenas e exclusivamente um deles seja 1. No caso da primeira opera\u00e7\u00e3o, somente o segundo bit (da esquerda para a direita) \u00e9 exclusivo 1 e por isso o valor obtido no c\u00e1lculo. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">    \/\/x: 0001 | y: 0101\n    x = x ^ y; \/\/ x recebe 0001^0101 = 0100\n    y = x ^ y; \/\/ y recebe 0100^0101 = 0001\n    x = x ^ y; \/\/ x recebe 0100^0001 = 0101<\/code><\/pre>\n\n\n\n<p>Observe que essa sequ\u00eancia de c\u00e1lculo \u00e9 baseada nos bits e n\u00e3o deve ser observada sua correspond\u00eancia com valores decimais. Por exemplo, o valor bin\u00e1rio 0100 \u00e9 o n\u00famero 4 em decimal, o qual n\u00e3o faz muito sentido no c\u00e1lculo.<\/p>\n\n\n\n<p>Por fim, foram apresentadas algumas formas de resolver um mesmo problema, trazendo inclusive uma forma pouco usual, que \u00e9 a utiliza\u00e7\u00e3o de operadores <em>bitwise<\/em>. Nunca se contente com apenas a primeira solu\u00e7\u00e3o encontrada pois ela pode n\u00e3o ser a melhor delas (no caso, a primeira exigia o uso adicional de uma vari\u00e1vel) e sempre pense bem o conjunto de testes que ser\u00e1 utilizado para a valiar sua solu\u00e7\u00e3o (no caso visto, a solu\u00e7\u00e3o com a opera\u00e7\u00e3o de divis\u00e3o n\u00e3o pode ter o zero como denominador).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Escrevo para apresentar a solu\u00e7\u00f5es algor\u00edtmicas para um problema apresentam uma grande varia\u00e7\u00e3o. Logicamente os problemas mais simples possuem menor quantidade poss\u00edvel de varia\u00e7\u00e3o, mas trago aqui um exerc\u00edcio tradicional introdut\u00f3rio de programa\u00e7\u00e3o para discutir essa quest\u00e3o. Enunciado: elabore um algoritmo que, dado dois valores, troque o conte\u00fado de um pelo do outro. Acredito que [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[3,58],"tags":[86],"class_list":["post-1346","post","type-post","status-publish","format-standard","hentry","category-c","category-codigo-com-analise","tag-bitwise"],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/posts\/1346","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/comments?post=1346"}],"version-history":[{"count":5,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/posts\/1346\/revisions"}],"predecessor-version":[{"id":1363,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/posts\/1346\/revisions\/1363"}],"wp:attachment":[{"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/media?parent=1346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/categories?post=1346"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.galirows.com.br\/meublog\/programacao\/wp-json\/wp\/v2\/tags?post=1346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}