Divagações...

quinta-feira, 16 de dezembro de 2010

quarta-feira, 10 de novembro de 2010

Maquina de Turing - Modelo de Computação

A maquina de turing é um modelo abstrato que nos diz qual a capacidade da computação. Isto significa que esta maquina, inventada por Alan Turing em 1936, representa uma conceitualização formal para verificar se  um procedimento ou algoritmo é ou não decivivel, isto é, se através de um conjunto fixo de instruções aplicadas sobre as entradas há a geração de saida em tempo habil, sem looping. Assim sendo, vale mencionar que todas as tecnolgias que temos hoje, em termos computacionais, obedecem aos mesmos principios, o embasamento teorico que as fundamentam não mudam ao longo do tempo, ou seja, assim como a maquina de turing, o que guia a computação são os proprios fundamentos dela, sendo as novas tecnologias baseadas nas primeiras premissas para computar, que são: uma função programa com as instruções de transformação de dados, um dispositivo de armazenamento, no caso da maquina de turing ( uma fita infinita à esquerda e à direita ), e um mecanismo de leitura/escrita.

Após esta introdução sobre maquina de turing e teoria da computação, segue a definição formal:

quinta-feira, 2 de setembro de 2010

Divagações...

Na minha concepção formada ao longo de minhas leituras e reflexões cheguei a conclusão que liberdade de expressão, liberdade de ir e vir, e liberdade de escolha estão todas condicionadas às regras a nossa volta, sejam elas impostas pela sociedade, "autoridades", ou instituições de toda sorte, como religiões e midia.

Nossas decisões, escolhas ou anseios são embasados em virtude dos estímulos externos, nunca visamos totalmente nossos interesses; o que queremos é o reconhecimento pelas pessoas do nosso circulo social, ser admirados e respeitados. Tais atitudes sempre estão de acordo com o meio externo a nossa realidade, estamos a todo momento nos adequando às situações para que sejamos bem-quistos.

Inserção - Arvores Binarias

Segue o codigo de inserção em arvores binarias e a explicação feita nos comentarios:

Árvores binárias

Uma outra forma de organizar dados em memoria principal é utilizando-se de árvores binárias. Elas são, assim como pilhas, filas, e listas, estruturas de dados que visam armazenar e manipular informações, mas apresentam uma peculiaridade, são estruturas hierárquicas, isto é, para cada nó que contém um certo dado, há uma relação de ordem entre o sucessor e o antecessor.
Para tornar claro esta ideia de hierarquia e ordem, veja o seguinte esboço:

 Terminologia:
-Nós: são os dados armazenados na árvore, que podem ser estruturas, chars, inteiros, etc.  
-Raiz da árvore: é o nó do topo da árvore, no exemplo o numero 10.
-Pai: são todos os nós acompanhados por outros dois nós, exemplo, 7 é pai de 2 e 8.
-Filhos:  são os nós descentendes de um nó pai ( antecessor ), exemplo, 7 e 15 são os filhos de 10.
-Folhas: são todos os nós do ultimo nível da arvore, os mais externos.

terça-feira, 1 de junho de 2010

Percepção

A maneira como enxergamos o mundo e como apreendemos os significados, por meio de nossos sentidos e de nosso pensamento, que modela a realidade a nossa volta, é designado pela função de percepção.
A percepção é o modo como encaramos e assimilamos a realidade, captando suas nuances e discernindo o que nos convem de acordo como ela está condicionanda. Em outras palavras, a percepção é a função capaz de apreender os signos a nossa volta, objetos, pessoas, semblantes, tudo relacionado aos pormenores que somos habilitados a captar.
Uma percepção condicionada e submissa à pensamentos pode ter seu modo de apreender a realidade

Autoconhecimento

A investigação de nós mesmos traz luz a elucidação de nossa percepção, o modo como encaramos o mundo, além de revelar pontos fortes e fracos que carregamos conosco. A partir do autoconhecimento seremos capazes de nos entender no que diz respeito ao trato com as pessoas que nos circunda, possibilitando-nos aperfeiçoarmos como ser humano, elevando o nível das relações interpessoais, bem como para minimizar nossos vícios para uma interação mais saudável.
Para lapidar a mente e ir de encontro a seus paradigmas e/ou pensamentos arraigados ao longo do tempo, cumpre-nos observar os pensamentos de maneira a desmascarar possíveis crenças deturpadas, as quais foram assimiladas durante nosso desenvolvimento e que limitam nosso espaço de ação.
Ainda o autoconhecimento possibilita trazer à tona condicionamentos que nem imaginávamos carregar, imagens mentais que criamos ou aceitamos do meio externo sem um senso critico adequado, que limitam e trazem hesitação quando de suas manifestações.

sexta-feira, 28 de maio de 2010

Pilha - palindromo

Outra utilização para a qual pode-se destinar o uso de pilhas é na verificação se uma certa palavra é ou não palindromo. Uma palavra é considerada palindromo quando sua escrita coincide tanto na ordem normal, quanto na inversa. Por exemplo, 'arara' e 'osso' podem ser lidas tanto da esquerda bem como da direita, ou de trás para frente, obtendo o mesmo siginificado. Segue um codigo em C++ que analisa se uma palavra é palindromo, utlizando do auxilio de pilhas:

quarta-feira, 21 de abril de 2010

Pilhas

Pilhas são estruturas de dados que visam armazenar elementos em termos do seguinte conceito: o ultimo elemento inserido é o primeiro elemento que será removido, são conhecidas como estruturas LIFO ( last in, first out ). São denominadas em analogia a pilhas de pratos ou livros, que para não corromper a estrutura é preciso tirar o primeiro elemento e assim por diante, até a pilha esvaziar. Para elucidar como as pilhas funcionam, e ententer como a sua lógica pode ser usufruia na confecção de programas para resolver determinados problemas  segue um codigo em C++, que utiliza de pilhas para converter numeros em decimais em numeros de base 2 a 9:

terça-feira, 13 de abril de 2010

Lista simplesmente ligada - Inserção

O esquema acima representa uma lista ligada, onde cada nó contem duas posições de memoria, um destinado as informações da lista, como nomes, valores, etc, e o segundo reservado aos ponteiros que fazem as referencias aos outros nós, seu sucessor e antecessor.

Algoritmo e Pensamento

Pensamentos são constituídos de palavras e imagens, e são manipulados pelo cérebro como forma de representar o mundo que nos cerca. Assim como nos algoritmos, para que o pensamento se realize, é necessário dados de entrada, ou estímulos externos, no caso da mente, que por meio destes pode evocar da memoria informações e efetuar computações.

Necessitamos da linguagem, constituida de palavras, para formular raciocínios e dar vazão a expressão dos pensamentos, analogamente, os algoritmos operam sobre dados, a fim de que alguma computação seja realizada. Sem a linguagem, os dados que usamos para nossas computações internas, não seriamos capazes de representar nosso pensamento, embora algumas correntes da psicologia afirmam que antes mesmo de aprendermos um idioma estamos aptos a modelar o mundo de outras formas. É o modelo, input/output, dados (algoritmos) ou estímulos (ambiente), que gera respostas de acordo com as entradas, que no caso dos algoritmos são deterministicas, e no nosso caso, subjetivas, intrínsecas aos nossos valores pessoais e/ou crenças.

Sobrecarga de operadores

As linguagens de programação, como C++, possuem tipagem forte, isto é, mantem associado aos tipos que variaveis podem assumir regras bem definidas. Em outras palavras, os tipos float, int, double, tem caracteristicas que as diferenciam, com um conjunto de operaçoes proprias. Por exemplo, o tipo int alem das operações aritmeticas, suporta o modulo de um numero, mod, o qual retorna o resto de uma divisão, operação não aceita em um float ou double. Com essas informações quero mostrar o mecanismo de conceber novos tipos de dados genericos, em C++, onde o programador é o responsavel por definir as operações sobre eles, a sobrecarga de operadores.

Esse topico de C++ destina-se a aplicar os operadores nativos ( +, -, *, / , <<, >> ) para os da


segunda-feira, 12 de abril de 2010

Fila

Filas são construidas em termos de listas ligadas, mas sua conceituação difere na maneira comos os dados são inseridos e removidos. Nesse caso, as filas são conhecidas como estruturas FIFO ( first in, first out ), ou seja, o primeiro elemento inserido, é o primeiro elemento que sai. As filas existem para suprir a necessidade de estabelecer uma dada ordem entre conjuntos de elementos. Por exemplo, uma fila de acesso a uma impressora, onde o primeiro processo que chega é o primeiro que toma os recursos para impressão, e também, o acesso aos dados de um servidor, onde as ordens de requisição obedecem uma ordem, implementados, possivelmente por uma fila.


Lista simplesmente ligada

Listas ligadas são um outro tipo de estrutura de dados, e em conjunto com as estruturas nativas da linguagem de programação, vetores e matrizes, visam manejar e organizar os dados de um determinado modo. As listas ligadas foram criadas para contornar o problema de estruturar os dados em vetores e matrizes, que dispondo os dados de modo sequencial, com acesso indexado, apresentam a desvantagem de lenta velocidade de inserção e remoção de elementos, visto que é preciso alterar todo o conjunto em caso de uma remoção no inicio de um vetor, reposicionando todos os demais, o que consome muito tempo de computação.


quinta-feira, 25 de fevereiro de 2010

Filosofia da programação

Programar é a arte de encontrar soluções, crias novas ideias, implementar maneiras mais eficazes de resolver problemas computáveis. Tudo isso instiga o programador a dar o melhor de si, a transcender suas habilidades, para, finalmente, sentir o prazer do 'insight' que sua mente proporciona ao encontrar o que aguçava sua engenhosidade: o desafio.
O desenvolvimento traz consigo o prazer de gerar uma nova solução, sempre tendo em mente a ideia de que fomos capazes de escrever os codigos e ver os resultados sendo executados pela maquina de acordo com o prentendiamos. Após percorrido o caminho árduo de desenvolver o código para satisfazer os requisitos do problema, o sentimento de realização traz a recompensa ao programador, trabalho cumprido, admiração e respeito por tê-lo feito. É da natureza humana se sentir apreciado e contribuir com trabalhos que possa trazer recompensas para as pessoas que nos cerca quanto para nós mesmos. Esse sentimento permeia o programador quando da finalização de um projeto, bom, ao menos no meu caso.

quarta-feira, 24 de fevereiro de 2010

Estruturas de dados - conceitos

Para a estruturação de dados de forma sistematica e organizada existem varias estruturas de dados, cada qual com uma finalidade especifica. Alem das estruturas basicas, como os vetores, matrizes e structs ( registros ), é possivel combiná-las, tal como um vetor de registros por exemplo, para formar uma estrutura de dados mais complexa. A maneira de organizar os dados de um programa pode ser modelado em termos dessas estruturas fornecidas pela linguagem.

Na natureza selvagem

Virtudes, principios, valores, ideias, são todos

Algoritmo - Recursividade

A recursividade permite modelar algoritmos de modo a alcançar a solução através da definição do problema em termos de si mesmo. Em outras palavras, podemos construir um algoritmo, tendo em vista que sua resolução é composta de chamadas a suas instruções até que uma condição de parada seja atendida; de natureza recursiva, a fim de facilitar a confecção do mesmo, pois se torna fácil pensar na solução do problema dessa maneira. A idéia chave por trás dos algoritmos recursivos, consiste em dividir o problema em partes menores até que uma de suas partes seja resolvida diretamente, sem uma chamada ao próprio código, sendo esta ultima execução direta denominada condição de parada.

Algoritmo - Top Down

Com os posts anteriores é possível escrever algoritmos para uma ampla gama de problemas. No entando, as vezes, nos sentimos desnorteados quanto ao rumo que se deve tomar quando do desenvolvimento de um algoritmo para resolver um dado problema. Neste post vou abordar uma técnica que utilizo quando escrevo meus algoritmos.

Esta técnica é denominada top-down, que consiste em um paradigma de atacar o problema de forma gradual. Após o entendimento completo do problema, basta dividi-lo em partes menores para que os detalhes sejam tratados individualmente e a solução como um todo seja alcançada com a união das resoluções de todas as partes. Escrever algoritmos usando top-down facilita a maneira de encarar os problemas, pois dividir um problema inicialmente complexo em partes de solução trivial, propicia 'insights' mentais que nos revelam o caminho que o algoritmo deve seguir.

Algoritmo - Registros

No post anterior abordei a implementação de vetores e matrizes, estruturas de dados básicas que fornecem meios de agrupar dados de um mesmo tipo. Neste post será tratado a implementação de uma estrutura mais sofisticada que permite reunir dados sob um mesmo nome; denominadas estruturas (em C) ou registros em linguagem algoritmica.

Os registros são agrupamentos de dados, possivelmente heterogéneos (real, inteiro, lógico, carácter, literal), que visam oferecer meios mais simples de manipular informações relacionados que o projetista do algoritmo quer manter unidas. Por exemplo, pense em um algoritmo que implemente operações sobre numero de empregados, valor do salário, departamento dos projetos, lucros obtidos de uma empresa. A manipulação de tais dados se torna trivial com a utilização dos registros, pois por meio de um rotulo (identificador do conjunto de dados) é possível acessar os dados-membros do conjunto.

Algoritmo - Vetores e matrizes

Para facilitar a manipulação de muitos dados ao mesmo tempo uma estrutura de dados homogênea é disponibilizada. Para tais implementações usa-se vetores e matrizes.
Vetores são posições contíguas de memória onde o armazenamento é realizado de modo sequencial. Já as matrizes são coleções de dados que podem conter mais de uma dimensão, matrizes planas, que são representadas por linhas e colunas (as mesmas usadas em matemática) e matrizes de duas ou mais dimensões. Tente usar seu poder de abstração para visualizar uma matriz e enxergá-la como um cruzamento de linhas e colunas, onde cada célula representa uma porção de memoria para armazenar um dado elemento.
Todos os tipos de dados apresentados nos posts anteriores são suportados por vetores e matrizes, os quais podem ser de inteiros, reais ou caracteres (chamados usualmente de strings).

Para ilustrar melhor como funcionam tais estruturas segue abaixo suas construções:

declare soma[10]: inteiro;
declare media[100] : real;
declare nomes[20][100] : caracter;

Representação do vetor soma[10]:
Esta é a maneira como o computador armazena vetores na memória RAM. As posições representas de E1 até E10 são os elementos propriamente ditos e sua referência é feita por meio dos indices, os quais são numerados de 1 a 10 trazendo a tona o elemento em sua localização.

Em pormenores, a memória principal do computador implementa o vetor como uma sequência de células que são referenciadas pelo seu endereço. O endereço de uma célula é o modo como o computador sabe a localização de um elemento em um vetor ou matriz. Para acessarmos um determinado elemento usamos índices, que varrem as posições do primeiro elemento até o último.

Os tipos dos vetores soma[10] e media[100] definidos acima indicam quais as operações são permitidas serem efetuadas com os valores e a faixa de precisão que o tipo admite. Já na declaração nomes[20][100] podemos guardar 20 nomes de tamanho 100, isto é, representa uma matriz de 20 linhas, as quais possuem 100 colunas; podendo ser armazenado em cada linha um nome de no máximo 100 caracteres.

Para a escrita e saída dos dados e manipulação dos mesmos, as seguintes operações
são necessárias:

Leitura/Escrita de vetores:

para i=1 ate 10 passo 1 faça
leia soma[i]; //lê o valor e guarda o elemento na posição i
escreva "Valor contido em: ", soma[i];
fim-para

Leitura/Escrita de matrizes:

para i=1 ate 20 passo 1 faça
para j=1 ate 100 passo 1 faça
leia nomes[i][j];
fim-para
fim-para

Para a inserção de dados em uma matriz foi preciso dois índices, pois é necessário controlar suas linhas e colunas. A referencia as linhas é efetuada por meio do índice i, já as colunas é por intermédio do índice j.

Qualquer duvida sobre como implementar ou operar sobre as estruturas homegeneas de dados deixe seu comentário e quando possível responderei.

Algoritmo - Estrutura de repetição

Estruturas de repetição são criadas para que diversas instruções sejam executadas um derteminado número de vezes. Elas servem para implementar ações de modo a automatizar os comandos até que uma condição seja satisfeita. Há duas maneiras de construirmos nossas estruturas de repetição: sabendo a condição de parada previamente ou quando desconhecemos seus limites. Exemplificarei abaixo:

estrutura de repetição controlada por contador:
para i=1 ate f passo 1 faça
instrução 1;
instrução 2;
instrução n;
fim-para

Algoritmo - Estrutura condicional

Veremos neste post como implementar controle de fluxo nos algoritmos. Controle de fluxo significa controlar quais blocos de comandos serão executados em função de uma comparação realizada nas instruções se e senao.

Os comandos se e senao são assim definidos:
se ( condicao )
instrução 1;
instrução 2;
instrução n;
senao
instruções 1 ... n;
instruções em caso de a condição acima resultar em valor lógico falso.

Algoritmo - Entrada/Saida de dados

No post anterior escrevi a definição de algoritmos. Neste tópico vamos aprender como modelar
nossos próprios algoritmos por meio de uma linguagem conhecida como portugol.
Primeiramente é necessário definir quais os objetivos do nosso algoritmo, ou seja, a função
que ele vai desempenhar de acordo com as necessidades do usuário. Após realizada a análise do problema basta traduzí-lo em comandos para execução sequencial. Para tanto é necessário representar os dados (entradas fornecidas pelo usuário) através de variáveis (segmentos de memorias com endereço referenciável) para que as informações sejam manipuladas pelo algoritmo e forneça a saída desejada pelo utilizador.

Algoritmos - Definição

Todo bom profissional da area de TI modela seus programas através de algoritmos, os quais especificam de maneira clara e objetiva quais os passos que o programa deve tomar no decorrer de sua execução.
Uma das possiveis definições de algoritmo seria a que segue: um conjunto de instruções/comandos que visam obter a solução de um problema por meio de sua execução sequencial ate que as saidas (resultados) corretas do algoritmo seja atingido. Em outras palavras, comandos que manipulam dados, os processa por intermedio de operações logicas e/ou aritmeticas e gera um resultado com sentindo agregado aos própositos do usuario.
Para a confecção de um algoritmo é necessario uma notação, que inclui comandos de entrada e saida de dados, declarações de variaveis, definições de constantes, estruturas de controle de fluxo e estruturas de repetição.
Nos próximos topicos abordarei cada um desses itens explicando como escrever seus proprios algoritmos em uma linguagem portugol (pseudo-codigo escrito em portugues).