Programação • Lógica

Lógica e Algoritmos

Subtópico da área de Programação com foco em raciocínio algorítmico, estruturas fundamentais e implementação prática em Python e C++.

Portal

Fundamentos Algorítmicos e Paradigmas

Regra de Ouro: Um algoritmo é uma sequência finita de passos lógicos e bem definidos para resolver um problema. A lógica é independente da linguagem de programação usada.

Comparativo de Abordagem: Python vs. C++

Característica Python C++
Tipagem Dinâmica e Forte (interpretado em tempo de execução). Estática e Forte (compilado para código de máquina).
Gerenciamento de Memória Automático via Garbage Collector e Contagem de Referências. Manual ou via Smart Pointers (RAII). Perto do hardware.
Foco de Aplicação Prototipagem rápida, Data Science, Automação, Scripting. Sistemas operacionais, Game Engines, Programação de Baixo Nível.

1. Variáveis, Tipos de Dados e Atribuição

Variáveis são posições nomeadas de memória reservadas para armazenar dados durante a execução.

2. Operadores Aritméticos, Relacionais e Lógicos

Combinam valores e variáveis para retornar novos dados ou decisões booleanas.

3. Controle de Fluxo Condicional

Altera o caminho de execução do código com base em condições lógicas.

Estruturas if / else / elif

Exemplo de verificação de maioridade ou categorias de acesso:

# Python: Estruturas Condicionais
idade = 18

if idade >= 18:
    print("Acesso Concedido: Maior de Idade")
elif idade >= 16:
    print("Acesso Concedido com Autorização")
else:
    print("Acesso Negado")
// C++: Estruturas Condicionais
#include <iostream>

int main() {
    int idade = 18;

    if (idade >= 18) {
        std::cout << "Acesso Concedido: Maior de Idade\n";
    } else if (idade >= 16) {
        std::cout << "Acesso Concedido com Autorizacao\n";
    } else {
        std::cout << "Acesso Negado\n";
    }
    return 0;
}

4. Laços de Repetição (Loops)

Iteram sobre blocos de código enquanto uma condição for satisfeita ou por uma quantidade definida de passos.

Iteração Determinada (For) e Indeterminada (While)

# Python: Loop For e While
# Imprimir de 0 a 4
for i in range(5):
    print(f"Iteracao For: {i}")

# Loop controlado por condição
contador = 0
while contador < 3:
    print(f"Iteracao While: {contador}")
    contador += 1
// C++: Loop For e While
#include <iostream>

int main() {
    // Loop For
    for (int i = 0; i < 5; i++) {
        std::cout << "Iteracao For: " << i << "\n";
    }

    // Loop While
    int contador = 0;
    while (contador < 3) {
        std::cout << "Iteracao While: " << contador << "\n";
        contador++;
    }
    return 0;
}

5. Estruturas de Dados Homogêneas: Arrays e Listas

Coleções contíguas de dados acessadas via índices numéricos indexados em zero.

6. Estruturas Multidimensionais: Matrizes

Arrays de arrays dispostos em linhas e colunas (grade bidimensional).

# Python: Matriz 2x3
matriz = [
    [1, 2, 3],
    [4, 5, 6]
]

for linha in matriz:
    for elemento in linha:
        print(elemento, end=" ")
    print()
// C++: Matriz 2x3
#include <iostream>

int main() {
    int matriz[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << matriz[i][j] << " ";
        }
        std::cout << "\n";
    }
    return 0;
}

7. Funções, Parâmetros e Modularição

Blocos de código reutilizáveis projetados para realizar uma tarefa específica, recebendo entradas (parâmetros) e devolvendo saídas (retorno).

# Python: Definição de Função
def calcular_area_retangulo(base: float, altura: float) -> float:
    return base * altura

resultado = calcular_area_retangulo(5.0, 3.0)
print(f"Area: {resultado}")
// C++: Definição de Função
#include <iostream>

double calcularAreaRetangulo(double base, double altura) {
    return base * altura;
}

int main() {
    double resultado = calcularAreaRetangulo(5.0, 3.0);
    std::cout << "Area: " << resultado << "\n";
    return 0;
}

8. Gerenciamento de Memória: Ponteiros e Referências

Enquanto linguagens de alto nível abstraem a memória, o C++ permite manipulação direta de endereços via ponteiros.

// C++: Demostração de Ponteiro e Referência
#include <iostream>

void incrementarPorReferencia(int &valor) {
    valor++; // Altera diretamente o valor original
}

int main() {
    int valor = 10;
    int* ptr = &valor; // 'ptr' guarda o endereço de 'valor'

    std::cout << "Valor Original: " << valor << "\n";
    std::cout << "Endereco na RAM (&valor): " << ptr << "\n";

    incrementarPorReferencia(valor);
    std::cout << "Apos Incrementar: " << valor << "\n";

    return 0;
}

9. Algoritmos de Busca

Métodos para localizar um elemento dentro de uma estrutura de dados.

Busca Linear vs. Busca Binária

Algoritmo Pré-requisito Complexidade Pior Caso
Busca Linear Nenhum (funciona em listas desordenadas). $\mathcal{O}(n)$ — Percorre item por item.
Busca Binária O array obrigatoriamente deve estar **ordenado**. $\mathcal{O}(\log n)$ — Divide o espaço de busca pela metade a cada passo.
# Python: Busca Binária Iterativa
def busca_binaria(arr, alvo):
    inicio = 0
    fim = len(arr) - 1

    while inicio <= fim:
        meio = (inicio + fim) // 2
        if arr[meio] == alvo:
            return meio # Retorna o índice encontrado
        elif arr[meio] < alvo:
            inicio = meio + 1
        else:
            fim = meio - 1

    return -1 # Não encontrado

dados = [10, 20, 30, 40, 50, 60, 70]
print("Indice do 40:", busca_binaria(dados, 40))

10. Algoritmos de Ordenação

Reorganizam elementos de uma lista segundo uma ordem definida (crescente ou decrescente).

// C++: Bubble Sort
#include <iostream>
#include <vector>

void bubbleSort(std::vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // Troca os elementos de lugar
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    std::vector<int> lista = {64, 34, 25, 12, 22, 11, 90};
    bubbleSort(lista);

    std::cout << "Lista Ordenada: ";
    for (int x : lista) std::cout << x << " ";
    std::cout << "\n";
    return 0;
}

11. Análise de Complexidade de Algoritmos (Notação Big-O)

Mede a eficiência do tempo de execução ou do consumo de memória de um algoritmo à medida que o tamanho da entrada ($n$) cresce.

12. Boas Práticas e Legibilidade de Código

  1. Nomes Significativos: Prefira nomes descritivos (ex: total_vendas) sobre nomes vagos (ex: x, data).
  2. Princípio DRY (Don't Repeat Yourself): Se um bloco de código se repete, transforme-o em uma função reutilizável.
  3. Indentação e Formatação: Mantenha a consistência (ex: 4 espaços para Python ou padrão da equipe para C++).
  4. Comentários Úteis: Explique o **porquê** a regra de negócio existe, não o que a linguagem já deixa óbvio.

13. Técnicas de Depuração (Debugging)

Diagnóstico sistemático para localizar e corrigir bugs no fluxo lógico.

ANEXO A — Checklist de Validação Algorítmica

ANEXO B — Tabela Verdade dos Operadores Lógicos

Condição A Condição B A AND B A OR B NOT A
V (True) V (True) V (True) V (True) F (False)
V (True) F (False) F (False) V (True) F (False)
F (False) V (True) F (False) V (True) V (True)
F (False) F (False) F (False) F (False) V (True)

ANEXO C — Exemplos de Manipulação de Entrada e Saída

Python (Leitura de Dados)

# Leitura e conversão de tipos em Python
nome = input("Digite seu nome: ")
idade = int(input("Digite sua idade: "))
altura = float(input("Digite sua altura (m): "))

print(f"Usuario {nome}, {idade} anos, {altura}m de altura.")

C++ (Leitura de Dados)

// Leitura de dados em C++ usando std::cin
#include <iostream>
#include <string>

int main() {
    std::string nome;
    int idade;
    double altura;

    std::cout << "Digite seu nome: ";
    std::cin >> nome;

    std::cout << "Digite sua idade: ";
    std::cin >> idade;

    std::cout << "Digite sua altura: ";
    std::cin >> altura;

    std::cout << "Usuario " << nome << ", " << idade << " anos, " << altura << "m de altura.\n";
    return 0;
}

ANEXO D — Comparativo de Escala da Notação Big-O

Tamanho Entrada ($N$) $\mathcal{O}(1)$ $\mathcal{O}(\log n)$ $\mathcal{O}(n)$ $\mathcal{O}(n \log n)$ $\mathcal{O}(n^2)$
10 1 op ~3 ops 10 ops ~33 ops 100 ops
100 1 op ~7 ops 100 ops ~664 ops 10.000 ops
1.000 1 op ~10 ops 1.000 ops ~9.965 ops 1.000.000 ops