A arte da programação
A arte da programação vai além de escrever código. Envolve nosso processo de pensamento, abordagem de solução de problemas e o impacto que causamos no mundo. A programação é uma linguagem criativa que dá vida às ideias e nos permite nos expressar por meio da tecnologia. Ela nos desafia a pensar de forma inovadora, encontrar soluções não convencionais e expandir nossa compreensão do mundo e de nós mesmos. Este vídeo explora conceitos fundamentais de programação, desde sintaxe básica e estruturas de dados até algoritmos avançados e paradigmas de programação. Vamos começar.
Quando se trata de editar código, existem dois tipos principais de ferramentas: editores de texto e IDEs. Enquanto os editores de texto se concentram na edição de texto simples, os IDEs fornecem recursos adicionais. No entanto, para a maioria dos propósitos, a distinção entre os dois não importa muito, e os termos podem ser usados de forma intercambiável. Opções populares para editores de texto e IDEs incluem Vim, Atom, Sublime Text, Eclipse, IntelliJ, PyCharm e Visual Studio Code. O Visual Studio Code, em particular, é altamente personalizável e amplamente recomendado.
Para executar o código, precisamos compilá-lo em código de máquina, que os computadores entendem. Isso requer a instalação de um compilador de linguagem ou tempo de execução. Linguagens diferentes têm seus próprios compiladores ou tempos de execução, como GCC, Java SDK, interpretador Python, tempo de execução Node.js e SDK .NET. Não é necessário entender os detalhes dessas ferramentas; tudo o que você precisa saber é instalar um idioma para executar seu código.
A execução do código envolve o uso do terminal, que fornece acesso à interface de linha de comando. Os terminais comumente usados incluem Powershell e Bash. O terminal nos permite executar comandos como criar diretórios, listar arquivos e executar programas. Gerenciadores de pacotes, como npm para Node.js e pip para Python, podem ser usados para instalar software de repositórios por meio da linha de comando. O Git, um sistema de controle de versão, é essencial para gerenciar alterações de código e colaborar com outras pessoas.
Para começar a codificar, você precisa de um editor de texto ou IDE adequado, um compilador de linguagem e conhecimento básico dos comandos do terminal. O Visual Studio Code é uma escolha recomendada para um editor de texto ou IDE. Instalar uma linguagem de programação e familiarizar-se com os comandos do terminal permitirá que você escreva e execute o código. Aprender linguagens de programação envolve entender sua sintaxe, ambiente e convenções. Diferentes idiomas têm níveis variados de complexidade, mas todos compartilham semelhanças em estrutura e conceitos.
A saída de impressão em diferentes linguagens de programação pode ser feita usando funções ou métodos específicos para cada linguagem. Por exemplo, Python tem a função de impressão integrada, JavaScript tem o método console.log e Java e C++ têm sua própria sintaxe para imprimir na saída padrão.
Variáveis são usadas para armazenar valores de diferentes tipos de dados. As variáveis são declaradas, definidas e inicializadas com valores. As linguagens de programação podem ser digitadas estaticamente ou dinamicamente e têm sintaxe diferente para variáveis. A tipagem estática requer declaração explícita do tipo de variável, enquanto a tipagem dinâmica não. As variáveis têm escopo, que determina onde elas podem ser acessadas e usadas em um programa. O escopo pode ser global ou local e permite uma melhor organização e prevenção de erros.
Os tipos de dados representam diferentes tipos de dados, como strings, booleanos, inteiros, números de ponto flutuante, caracteres e matrizes. As estruturas de dados fornecem uma maneira de organizar e manipular dados. Estruturas de dados populares incluem arrays, pilhas, heaps, árvores, listas encadeadas, tabelas de hash, mapas de hash e gráficos. Arrays e mapas são duas estruturas de dados comumente usadas com vários aplicativos.
Em resumo, a programação é uma arte que abrange pensar, resolver problemas e moldar o mundo por meio do código. Envolve o uso de editores de texto ou IDEs, execução de código por meio de compiladores ou tempos de execução e compreensão de comandos de terminal e controle de versão. Aprender linguagens de programação requer compreensão da sintaxe, variáveis, tipos de dados e estruturas de dados. O vídeo fornece uma visão geral de alto nível desses conceitos para você começar sua jornada de programação.
- 2023.05.11
- www.youtube.com
A arte de escrever software
Os computadores, assim como os instrumentos musicais, são máquinas meticulosamente trabalhadas, projetadas para executar tarefas específicas com base nas instruções que recebem. Essas instruções, escritas em código, são o software que orienta suas operações. Assim como a notação musical é o código usado pelos compositores, os programadores de computador usam o código de software para criar programas.
A programação pode ser uma fonte de alegria e satisfação, semelhante aos sentimentos experimentados por poetas ou músicos. Os primeiros computadores eram fascinantes e poderosos para aqueles que gostavam de resolver problemas e complexidade. Eles operavam em velocidades surpreendentes, capazes de resolver uma ampla gama de problemas, desde que fossem expressos usando os comandos nativos do computador. No entanto, os computadores são inerentemente burros e requerem instruções precisas para entender o que fazer. Os primeiros programadores tinham que escrever linguagem de máquina usando números que representavam comandos binários. Esse processo era tedioso e sujeito a erros, levando ao desenvolvimento de linguagens de programação mais amigáveis.
A introdução de linguagens de alto nível, como Fortran e COBOL, tornou a programação mais acessível. Os programadores podiam expressar suas instruções usando fórmulas científicas familiares ou declarações lógicas que fizessem sentido para eles. Os compiladores foram então usados para traduzir essas instruções na linguagem binária do computador. Esse avanço desencadeou a revolução do software, pois os programadores não precisavam mais aprender a linguagem de máquina específica de cada computador.
Ao longo dos anos, centenas de linguagens de programação foram desenvolvidas para atender a diferentes necessidades. A lacuna entre essas linguagens e a linguagem de máquina aumentou, permitindo que os programadores se concentrem no que desejam alcançar, em vez dos detalhes de baixo nível. À medida que a computação se tornou mais pessoal, as linguagens de programação tornaram-se mais diversificadas e fáceis de usar. As pessoas agora se comunicam rotineiramente com computadores, dizendo-lhes o que fazer, como calcular médias ou organizar dados. A programação tornou-se uma ferramenta para capacitar os indivíduos, permitindo-lhes customizar e adaptar os sistemas de computador às suas necessidades.
Escrever software envolve não apenas codificar, mas também definir como os dados são representados e organizados. Os dados podem ser organizados em strings, listas, tabelas, árvores e muito mais, dependendo dos requisitos. A escolha da linguagem e da estrutura de dados é crucial para resolver problemas de programação de forma eficaz. Os programadores criam procedimentos passo a passo conhecidos como algoritmos para resolver problemas. Esses algoritmos especificam as operações necessárias para alcançar os resultados desejados. No entanto, encontrar o algoritmo mais eficiente para um determinado problema pode ser uma tarefa complexa. Requer raciocínio cuidadoso, concentração e, às vezes, amplo conhecimento em áreas especializadas.
O desenvolvimento de software é um empreendimento desafiador e criativo que requer manter vários aspectos em mente simultaneamente. Os programadores se adaptam constantemente aos avanços da tecnologia, ultrapassando os limites do que os computadores podem alcançar. Eles buscam elegância e coerência em seu código, criando um software funcional e esteticamente agradável. Por meio de seus esforços, os programadores de software expandiram nossas capacidades, permitindo-nos aproveitar as vastas quantidades de informações e interagir com o mundo de maneiras que antes eram consideradas mágicas. A programação é a força motriz por trás de fazer os computadores funcionarem e moldar o mundo de alta tecnologia em que vivemos hoje.
- 2014.11.17
- www.youtube.com
C++ Tutorial para Iniciantes - Curso Completo
C++ Tutorial para Iniciantes - Curso Completo
00:00:00 - 01:00:00 Este vídeo é um tutorial para iniciantes que desejam aprender a codificar em C++. Abrange os fundamentos do trabalho com strings, números e variáveis. Ele também apresenta o conceito de importação de código de outros arquivos.
01:00:00 - 02:00:00 Este tutorial C++ para iniciantes cobre como construir uma calculadora de quatro funções. O tutorial explica como inserir dados, verificar a igualdade do operador e executar o código com base nessa condição.
02:00:00 - 03:00:00 Este vídeo fornece uma introdução básica à programação C++, com foco no uso de loops for para calcular um resultado específico. A função que está sendo demonstrada calcula o resultado de um número elevado a uma potência específica.
03:00:00 - 04:00:00 Neste tutorial C++ para iniciantes, o instrutor demonstra como usar a herança para estender a funcionalidade em uma hierarquia de classes. A herança permite que uma classe tenha a mesma funcionalidade que outra classe, enquanto estende essa funcionalidade com recursos adicionais. O instrutor também demonstra como substituir funções herdadas para alterar o comportamento de uma classe.
Parte 1
- 00:00:00 Este tutorial em vídeo ensina aos iniciantes como escrever código C++ básico. O primeiro passo é instalar um editor de texto e um compilador c++, ambos incluídos no pacote codeblocks. Em seguida, o tutorial mostra como configurar um projeto simples em codeblocks.
- 00:05:00 Este tutorial fornece uma breve introdução à linguagem de programação C++ e às ferramentas necessárias para escrever e executar programas C++. A primeira parte do tutorial mostra como instalar as ferramentas necessárias em um Mac, e a segunda parte aborda como criar um novo projeto C++ em blocos de código.
- 00:10:00 Neste tutorial em vídeo, o apresentador percorre os fundamentos da escrita de um programa c++. Ele aborda a necessidade de um projeto e arquivo c++, explica as funções e mostra como criar e executar um programa.
- 00:15:00 Este tutorial explica como escrever código básico em C++ e como usar instruções de impressão para enviar informações para o console.
- 00:20:00 Neste vídeo, o apresentador mostra como as variáveis são úteis na programação, fornecendo um exemplo de programa que imprime uma história. O apresentador então demonstra como criar e atribuir um valor a uma variável chamada "nome do personagem" que armazena o nome do personagem. A seguir, o apresentador demonstra como criar e atribuir um valor a uma variável chamada "idade" que armazena a idade do personagem. Por fim, o apresentador demonstra como usar uma variável para armazenar vários dados.
- 00:25:00 Neste vídeo, o apresentador apresenta o conceito de variáveis e mostra como utilizá-las para armazenar dados em um programa. Eles demonstram como acessar e manipular os dados armazenados em variáveis usando instruções de impressão. Por fim, eles mostram como incluir uma variável dentro de uma instrução print para que os dados sejam impressos em uma string separada.
- 00:30:00 Este vídeo apresenta o conceito de variáveis e tipos de dados em C++. Uma variável é um contêiner que armazena dados e você pode usá-la para armazenar qualquer tipo de informação. Strings são um tipo comum de variável e são uma sequência de caracteres. Você também pode usar inteiros para armazenar números inteiros ou inteiros negativos para armazenar números negativos. Você também pode armazenar números decimais em números inteiros.
- 00:35:00 Este tutorial aborda os fundamentos da programação com C++, começando com texto e números simples e passando para tipos de dados mais complexos, como strings e booleanos.
- 00:40:00 Este vídeo aborda como usar o comprimento das funções de string C++ e a indexação de strings para imprimir strings e determinar a localização de caracteres específicos em uma string e como modificar caracteres específicos em uma string.
- 00:45:00 O vídeo aborda os fundamentos do trabalho com strings em C++, incluindo como passar argumentos para funções e como usar diferentes funções matemáticas para manipular strings.
- 00:50:00 Neste tutorial C++, são abordados os fundamentos de números, adição, subtração, multiplicação e divisão. O operador de módulo também é introduzido, o que é útil para dividir dois números e calcular o restante. Finalmente, o armazenamento de números em variáveis é demonstrado.
- 00:55:00 Este tutorial C++ para iniciantes explica como usar funções matemáticas para resolver problemas. As funções incluem raiz quadrada, pow e round. A importação de código de outros arquivos também é explicada.
Parte 2
- 01:00:00 Neste tutorial C++ para iniciantes, o usuário é solicitado a inserir sua idade e nome. O programa então armazena as informações em uma variável chamada idade e imprime o nome e a idade do usuário.
- 01:05:00 Este tutorial em vídeo mostra como criar uma calculadora básica em c++ e como construir um jogo Mad Libs.
- 01:10:00 Este vídeo explica como criar e usar arrays em C++. As matrizes são semelhantes às variáveis, mas podem conter vários valores.
- 01:15:00 Este tutorial em vídeo explica os fundamentos dos arrays em C++. Uma matriz é um contêiner que pode armazenar várias partes de dados e você pode acessar elementos individuais por índice ou atribuindo um valor à propriedade "tamanho" da matriz.
- 01:20:00 Neste tutorial, o autor demonstra como criar uma função em C++. Uma função é um bloco de código que executa uma tarefa específica e pode ser reutilizado em todo o programa. O tipo de retorno da função pode ser void ou inteiro. O autor também demonstra como chamar uma função.
- 01:25:00 Neste vídeo, o autor explica como as funções funcionam e como elas podem ser reutilizadas. Ele também mostra como criar uma assinatura de função e como chamar uma função usando sua assinatura. Por fim, ele discute retornos em c++, que é quando uma função retorna informações ao chamador.
- 01:30:00 O vídeo discute como criar funções em C++ e como usar a palavra-chave return para indicar que a execução da função foi concluída. O vídeo também demonstra como usar a função de cubo para retornar o resultado do cubo de um número.
- 01:35:00 Neste tutorial, o autor ensina iniciantes sobre a instrução if em C++. Uma instrução if é uma estrutura de programação que permite que um programa responda a diferentes situações. O autor demonstra como usar uma instrução if para verificar condições e como criar instruções if mais complexas.
- 01:40:00 Este tutorial em vídeo explica como usar os operadores and e or em C++ para verificar duas condições. Se qualquer uma das condições for falsa, todo o bloco if será falso e o código não será executado.
- 01:45:00 Neste tutorial, o autor ensina iniciantes sobre instruções if, explicando como usar comparações para criar valores verdadeiros ou falsos. A função receberá dois números como entrada e retornará o maior.
- 01:50:00 Este vídeo explica como as comparações funcionam em C++ e como usar maior que, menor que e igual a para verificar se dois números são iguais ou maiores que ou iguais.
- 01:55:00 Este tutorial C++ para iniciantes ensina como construir uma calculadora de quatro funções, incluindo como inserir dados, verificar a igualdade do operador e executar o código com base nessa condição.
Parte 3
- 02:00:00 Neste tutorial em vídeo, é demonstrada uma função para converter um número inteiro em um dia da semana. A função é criada e uma instrução if é usada para determinar se o número do dia fornecido é um ou mais. Se for um, a função retorna "Domingo"; se não for um, a função retorna "segunda-feira".
- 02:05:00 Este vídeo explica como uma instrução switch pode ser usada para tornar o código em uma instrução if mais eficiente. O vídeo explica como criar uma instrução switch para cada dia da semana e demonstra a função imprimindo o dia da semana para um número passado como entrada.
- 02:10:00 Este vídeo fornece uma visão geral do vídeo "Tutorial C++ para Iniciantes - Curso Completo". O vídeo demonstra como usar um loop while para percorrer um bloco de código enquanto uma condição é atendida.
- 02:15:00 Este tutorial de C++ para iniciantes aborda os fundamentos dos loops, incluindo como criar um loop while e um loop do while. O vídeo também discute um loop infinito e como evitá-los. Finalmente, um loop for é demonstrado.
- 02:20:00 Este tutorial mostra como criar um jogo de adivinhação usando um loop while e um loop do while. O jogo é inicialmente injusto no sentido de que o usuário tem palpites ilimitados, mas o tutorial mostra como tornar o jogo mais justo impondo um limite de palpites.
- 02:25:00 Neste vídeo, o autor explica como os loops for funcionam e como eles podem ser usados em C++. Ele também mostra um exemplo de como os loops for podem ser usados para resolver um problema.
- 02:30:00 Neste vídeo, o autor explica o loop while, uma construção de loop em que uma variável muda cada vez que é executada. O loop for é uma construção semelhante, mas inclui uma declaração de variável, inicialização e condição de loop.
- 02:35:00 Este tutorial em vídeo demonstra como usar loops for para iterar o conteúdo de arrays, bem como construir uma função que eleva um número a uma potência específica.
- 02:40:00 Este tutorial em vídeo fornece uma introdução básica à programação C++, com foco no uso de loops for para calcular um resultado específico. A função que está sendo demonstrada calcula o resultado de um número elevado a uma potência específica.
- 02:45:00 Neste tutorial, o autor mostra como criar e usar um array bidimensional e discute como acessar elementos dentro dele.
- 02:50:00 Este tutorial em vídeo apresenta a linguagem C++ e demonstra como usar iteradores for e int para percorrer arrays de dados. Os loops for aninhados permitem fácil iteração de dados dentro de arrays.
- 02:55:00 Este vídeo explica o que é um ponteiro, como eles são úteis e como criá-los em C++.
Parte 4
- 03:00:00 Este vídeo fornece uma introdução à programação C++ para iniciantes, com exemplos de como usar variáveis e constantes para armazenar informações. O vídeo também demonstra como acessar endereços de memória para recuperar informações armazenadas neles.
- 03:05:00 Este vídeo fornece uma visão geral do vídeo "Tutorial C++ para Iniciantes - Curso Completo". No vídeo, o apresentador demonstra como acessar endereços de memória de variáveis usando ponteiros. Um ponteiro é apenas um endereço de memória que é apenas um tipo de dado, e você pode usá-lo para armazenar um ponteiro para uma variável diferente.
- 03:10:00 Este tutorial explica como usar ponteiros na programação e demonstra como desreferenciá-los para acessar o valor armazenado em um determinado endereço de memória. Além disso, o tutorial discute classes e objetos em c++ e demonstra como criar e usar uma classe.
- 03:15:00 Neste vídeo, um tutorial de c++ para iniciantes, o autor cria uma classe para representar livros. A classe tem dois atributos, o título e o autor. O autor então cria um objeto de livro e define o título e o autor.
- 03:20:00 Este vídeo ensina aos iniciantes como criar e trabalhar com objetos em C++. Um objeto é uma instância real de uma classe e uma classe é o modelo para um tipo de dados. Os objetos podem ser impressos e ter seus valores alterados.
- 03:25:00 Este vídeo explica como os Construtores funcionam em C++ e como eles podem ser usados para inicializar objetos com valores padrão.
- 03:30:00 Este tutorial em vídeo explica como criar um construtor C++ que aceita título, autor e páginas como valores de entrada. Uma vez inicializado, o construtor pode ser usado para criar um novo objeto sem ter que passar os valores toda vez.
- 03:35:00 Este vídeo explica como usar funções em C++ para determinar se um aluno tem honras ou não. As funções são modelos que cada objeto pode usar para retornar verdadeiro ou falso, dependendo do próprio GPA do objeto.
- 03:40:00 Este vídeo ensinará aos iniciantes como usar getters e setters em aulas de c++. Getters e setters permitem que você controle o acesso a atributos e elementos em suas classes. Este exemplo mostra como impor uma classificação válida para um filme usando getters e setters.
- 03:45:00 Neste tutorial de C++ para iniciantes, o autor demonstra como usar getters e setters para restringir as classificações que podem ser atribuídas a um objeto de filme. Se a classificação passada não for uma das classificações válidas, um erro será lançado ou a classificação não será definida.
- 03:50:00 Neste vídeo, o autor explica como definir classificações para vídeos usando C++. Primeiro, eles explicam como as classificações são representadas em C++, sendo uma classificação igual a um valor positivo, como 13, ou um valor negativo, como -3. Em seguida, eles demonstram como definir uma classificação para um vídeo usando uma função chamada definir classificação. Essa função recebe um parâmetro, que é uma string que representa a classificação. Se a classificação inserida for inválida, a função retornará uma string representando a classificação não classificada. Por fim, o autor demonstra como imprimir a classificação de um vídeo usando uma função chamada get rating. Esta função não aceita parâmetros e simplesmente retorna a classificação do vídeo.
- 03:55:00 Neste tutorial de C++ para iniciantes, o instrutor demonstra como herdar funções e como substituí-las em uma hierarquia de classes. Isso permite que uma classe tenha a mesma funcionalidade que outra classe, enquanto estende essa funcionalidade com recursos adicionais.
- 2018.08.24
- www.youtube.com
Introdução à Programação e Ciência da Computação - Curso Completo
Introdução à Programação e Ciência da Computação - Curso Completo
Este vídeo é um guia para iniciantes em programação e ciência da computação para aqueles com pouca ou nenhuma experiência em codificação. Abrange conceitos e técnicas fundamentais que se aplicam a qualquer linguagem de programação. O vídeo explica os fundamentos da escrita de código em um ambiente de desenvolvimento integrado (IDE) e enfatiza a importância da gramática de programação.
Os tópicos abordados no vídeo incluem:
- Introdução à programação e ciência da computação, incluindo sintaxe e regras de programação.
- Usando o console para saída de texto de um programa.
- Operações matemáticas básicas e o operador de módulo na programação.
- Imprimindo strings no console.
- Noções básicas sobre variáveis, tipos de dados e convenções de nomenclatura.
- Como as variáveis são definidas, referenciadas e manipuladas em programas.
- Explorando instruções if, elsif e else para execução condicional.
- Apresentando arrays como uma forma de armazenar variáveis relacionadas.
- Noções básicas de loops, incluindo loops for, loops while e loops do-while.
- Compreender diferentes tipos de erros de programação: erros de sintaxe, erros de tempo de execução e erros de lógica.
- Técnicas de depuração, como usar instruções de impressão, pontos de interrupção e comentários.
- Estratégias para evitar erros na programação.
- Trabalhar com funções para organizar o código e reduzir a repetição.
- Importando funções de bibliotecas e convenções de nomenclatura para funções.
- Diferentes tipos de funções e suas finalidades.
- Introdução aos dicionários como uma opção flexível de armazenamento de dados.
- Visão geral dos algoritmos de pesquisa, incluindo pesquisa linear e pesquisa binária.
- Programação recursiva e seus casos de uso, incluindo o conceito de caso base.
- Soft skills para ciência da computação, como resolução de problemas e planejamento.
- Usando pseudocódigo como uma ferramenta de planejamento para escrever código.
- Diferentes métodos para planejar e escrever código, incluindo fluxogramas e planejamento cronológico.
- Visão geral das linguagens de programação e recursos disponíveis para aprendizado.
O vídeo fornece uma introdução abrangente à programação e ciência da computação, oferecendo aos espectadores a base necessária para iniciar sua jornada de codificação. Ele também sugere recursos adicionais e sites para explorar mais o tópico.
- 00:00:00 Este vídeo aborda os pontos principais do vídeo, destinado a quem se interessa por ciência da computação e programação, mas não tem ideia de por onde começar e tem pouca ou nenhuma informação básica sobre codificação. O vídeo aborda os fundamentos da programação de computadores, que podem ser aplicados a toda e qualquer linguagem de programação que você queira aprender.
- 00:05:00 Este vídeo discute os fundamentos da programação, como escrever código em um ambiente de desenvolvimento integrado (IDEs) e a importância da gramática de programação.
- 00:10:00 Este vídeo apresenta programação e ciência da computação e aborda os fundamentos da sintaxe e regras de programação. O principal uso do console é a saída de texto do programa.
- 00:15:00 Este vídeo aborda matemática básica, incluindo aritmética, adição, subtração, multiplicação e divisão, bem como módulo, um operador básico em muitas linguagens de programação. Ele também abrange a impressão de cadeias de caracteres no console.
- 00:20:00 Este vídeo apresenta conceitos de programação e ciência da computação, incluindo variáveis, tipos e nomes. As variáveis primitivas incluem números inteiros, booleanos, flutuantes e duplos. Variáveis de string armazenam strings de caracteres. As variáveis char contêm um caractere. As variáveis são essenciais para armazenar informações em um formato que pode ser facilmente referenciado.
- 00:25:00 Este vídeo discute o que acontece quando definimos ou criamos variáveis, como referenciá-las e como manipulá-las para nossos programas. Os principais pontos a serem retirados são que as variáveis são simplesmente espaços na memória que armazenam um determinado valor e que podemos atualizar os números e seu lugar permanecerá constante em todo o código.
- 00:30:00 Uma variável é um lugar onde você pode armazenar informações durante a programação. As convenções de nomenclatura para variáveis são importantes para facilitar a leitura. Se uma condição em uma instrução if for verdadeira, o código entre chaves será executado. Existem duas instruções adicionais, elsif e eltons, que funcionam de maneira semelhante às instruções if. Se a condição em elsif for verdadeira, o código seguinte a elsif será executado. Caso contrário, o código seguinte elsif
será ignorado. Se a condição em elsif não for verdadeira, o código após elsif será ignorado e o código após a instrução if será executado. - 00:35:00 Uma matriz é uma lista de variáveis relacionadas entre si. Eles são úteis quando um programador deseja armazenar muitas variáveis contendo informações relacionadas entre si.
- 00:40:00 Um curso de introdução à programação e ciência da computação aborda arrays, índices, tamanho e arrays dentro de arrays. Loops também são cobertos.
- 00:45:00 Este vídeo aborda os diferentes tipos de loops, loops for, while e do while. Ele explica como configurar uma condição para um loop e como evitar um loop infinito.
- 00:50:00 Este vídeo aborda os três tipos de erros que podem ocorrer durante a programação: erros de sintaxe, erros de tempo de execução e erros de lógica. Os erros de sintaxe são os mais fáceis de corrigir, pois geralmente são algo que pode ser corrigido em segundos. Os erros de tempo de execução são causados por instruções em seu código que parecem logicamente sólidas, mas o computador fisicamente não tem como concluir a tarefa em um período de tempo razoável. Os erros lógicos são os mais irritantes e difíceis de depurar, pois muitas vezes podem levar os programas a não funcionarem conforme o esperado. Para depurar seu código, você deve testá-lo incrementalmente e procurar por erros de sintaxe e tempo de execução.
- 00:55:00 Se você encontrar um erro em seu código, poderá usar instruções de impressão e o console para determinar onde o código está errado, usar pontos de interrupção para rastrear a causa do erro e usar comentários para marcar código que se destina a você e não ao computador. Finalmente, são discutidas estratégias para evitar erros.
- 01:00:00 Neste vídeo, o instrutor aborda os fundamentos da programação e da ciência da computação, incluindo erros e funções. Ele continua explicando como os argumentos funcionam em uma função e como usar funções para reduzir a repetição no código.
- 01:05:00 Esta introdução em vídeo à programação e ciência da computação discute os quatro tipos diferentes de funções, suas finalidades e como usá-las em seu código. As funções podem ser úteis para organizar o código, economizar tempo e fazer grandes alterações no código sem ter que passar por todo o programa.
- 01:10:00 Neste vídeo, são apresentados os fundamentos da programação e da ciência da computação. A importação de funções de bibliotecas é explicada e as regras para nomear funções são discutidas. Regras para criar funções com base no tipo e número de argumentos também são introduzidas.
- 01:15:00 Neste vídeo, o instrutor explica os fundamentos da programação e da ciência da computação, incluindo funções, escopo e passagem de argumentos. Ele também aborda como criar funções que não retornam nenhum valor.
- 01:20:00 Neste vídeo, o apresentador analisa arrays, funções e dicionários. Arrays são como listas de valores que são armazenados juntos, e as funções retornam uma variável dependendo do caminho percorrido. Um pequeno detalhe a ser observado é que você não pode retornar um tipo de variável se já tiver definido a função para retornar outro tipo. As listas de matriz aumentam quando o tamanho da lista excede 10 elementos e os dicionários armazenam vários valores.
- 01:25:00 Um computador armazena dados de maneiras diferentes, o que pode ser difícil de entender. Um dicionário é um tipo de armazenamento de dados, que é mais fluido e fácil de organizar do que os arrays tradicionais. Algoritmos de busca são usados para encontrar rapidamente um dado específico em uma lista de valores.
- 01:30:00 Este vídeo apresenta o conceito de algoritmos de busca e sua eficiência. A pesquisa linear é um bom algoritmo básico para listas não classificadas, mas é ineficiente no pior cenário. A busca binária é um algoritmo de busca eficiente para listas ordenadas, aproveitando o fato de que a lista está ordenada.
- 01:35:00 O algoritmo de busca binária é mais rápido e eficiente do que uma busca linear para encontrar um item em uma lista ordenada. A função recursiva é um exemplo de uma instrução de programação recursiva. O caso base para uma instrução recursiva é um valor definido que todas as instruções recursivas devem atender. Se n não for menor ou igual a um, a instrução recursiva retornará a soma de n e, em seguida, o valor de retorno do método soma recursiva menos um.
- 01:40:00 Este vídeo apresenta programação e ciência da computação e explica por que a recursão é uma técnica útil. As soft skills necessárias para a ciência da computação incluem resolução de problemas e planejamento. O pseudocódigo é uma forma simplificada de programação que pode ajudar nesse planejamento.
- 01:45:00 Pseudocódigo é uma forma visual de planejar o código de computador, semelhante à construção de um esboço para um papel. Fluxogramas e escrever o que você deseja que o programa faça cronologicamente são dois métodos comuns.
- 01:50:00 Este vídeo apresenta conceitos de programação e ciência da computação, incluindo os diferentes métodos para planejar e escrever código e a importância do pseudocódigo. Ele também cobre diferentes linguagens de programação e seus usos.
- 01:55:00 Nesta série, o autor aborda os fundamentos da programação, que incluem sintaxe e regras, e ensina como aprender uma linguagem específica. Ele também fornece sites e recursos para ajudá-lo a começar.
- 2020.04.21
- www.youtube.com
Curso de Programação C++ - Iniciante ao Avançado
Curso de Programação C++ - Iniciante ao Avançado
O curso cobre diferentes aspectos da programação C++.
Os tópicos abordados:
-
Configurando um ambiente de desenvolvimento C++: Os vídeos fornecem uma visão geral de como configurar um ambiente de desenvolvimento C++ em várias plataformas. Isso inclui a instalação de compiladores diferentes e a configuração do Visual Studio Code para usar os compiladores e a biblioteca padrão C++. As instruções abrangem plataformas como Windows, Mac e Linux.
-
Noções básicas de programação em C++: os vídeos abordam conceitos fundamentais como variáveis, tipos de dados, funções e instruções de controle de fluxo. Eles explicam como declarar variáveis, definir funções e usar estruturas de controle como loops e instruções condicionais. Os vídeos também apresentam conceitos como comentários e a função principal em C++.
-
Manipulação de strings: vídeos específicos focam no trabalho com strings em C++. Eles explicam como comparar e concatenar strings usando funções como strcmp e strcat. Os vídeos também demonstram como copiar strings usando a função strcpy.
-
Arrays: os vídeos introduzem o conceito de arrays em C++. Eles abordam tópicos como declarar e inicializar arrays, acessar elementos usando ponteiros e imprimir arrays de caracteres.
-
Alocação dinâmica de memória e ponteiros: esses vídeos explicam como a memória é gerenciada em C++ e como usar técnicas de alocação dinâmica de memória para alocar memória adicional para um programa. Eles abrangem os conceitos de ponteiros, mapas de memória e unidades de gerenciamento de memória. Os vídeos também discutem como usar ponteiros com segurança, evitar travamentos e lidar com vários ponteiros apontando para o mesmo local de memória.
-
Modelos de função e funções lambda: os vídeos explicam como criar funções genéricas usando modelos de função em C++. Eles demonstram como o compilador pode gerar definições de função com base nos tipos de parâmetros passados. Além disso, os vídeos abrangem as funções lambda, que são funções anônimas que podem ser chamadas sem dar um nome a elas. Eles explicam a sintaxe e a especificação do tipo de retorno para funções lambda.
-
Classes e herança: esses vídeos apresentam o conceito de classes em C++ e explicam como definir variáveis e funções de membros em uma classe. Eles abordam tópicos como construtores, destruidores, especificadores de acesso (protegidos e privados) e o uso de vinculação estática e dinâmica para obter polimorfismo. Os vídeos também demonstram como criar e usar classes derivadas com base em classes pré-existentes usando herança.
-
Depuração e tratamento de erros: os vídeos fornecem orientação sobre a depuração de programas C++. Eles explicam como definir pontos de interrupção, examinar variáveis no escopo local e lidar com erros relacionados a ponteiros não inicializados e vazamentos de memória. Os vídeos também abordam conceitos como divisão de objetos e substituição de construtores de classe base.
-
Interfaces e polimorfismo: Alguns vídeos focam em interfaces e polimorfismo em C++. Eles explicam como usar vinculação dinâmica, referências e a palavra-chave override para obter comportamento polimórfico em programas. Os vídeos também abordam o especificador final, que pode ser usado para marcar um método virtual como final e impedir que ele seja substituído em classes derivadas.
-
Outros tópicos: Os tópicos adicionais abordados incluem parâmetros padrão, interface inserível de fluxo para impressão automática de fluxo de saída e utilização de interfaces para criar código mais legível.
O vídeo fornece instruções passo a passo, demonstrações e explicações para ajudar os iniciantes a aprender programação C++ desde a instalação e configuração até conceitos mais avançados, como programação orientada a objetos, gerenciamento de memória e polimorfismo. O conteúdo é adequado tanto para iniciantes que desejam aprender os fundamentos da programação C++ quanto para programadores experientes que desejam atualizar suas habilidades ou explorar tópicos específicos em profundidade.
Código: https://github.com/rutura/The-C-20-Masterclass-Source-Code
Capítulo 1: Configurando as ferramentas
- 00:04:32 Ferramentas de Desenvolvimento C++
- 00:11:06 Instalando compiladores C++ no Windows
- 00:24:27 Instalando o VS Code no Windows
- 00:28:00 Configurando o Visual Studio Code para C++ no Windows
- 00:57:27 Instalando compiladores C++ no Linux
- 01:04:02 Instalando o Visual Studio Code no Linux
- 01:07:40 Configurando o Visual Studio Code para C++ no Linux
- 01:22:45 Instalando compiladores C++ no MacOS
- 01:28:07 Instalando o Visual Studio Code no MacOS
- 01:30:16 Configurando o Visual Studio Code para C++ no MacOS
- 01:35:37 Compiladores Online
Capítulo 2: Mergulhando
- 01:43:01 Seu Primeiro Programa C++
- 01:55:56 Comentários
- 02:01:56 Erros e Avisos
- 02:13:12 Declarações e funções
- 02:31:34 Entrada Saída
- 02:49:57 Modelo de Execução de Programa C++ e Modelo de Memória
- 02:56:42 C++ Core Language VS Standard Library VS STL
Capítulo 3: Variáveis e tipos de dados
- 03:00:47 Variáveis e Tipos de Dados Introdução
- 03:05:05 Sistemas Numéricos
- 03:21:52 Inteiros
- 03:40:44 Modificadores inteiros
- 03:54:00 Números Fracionários
- 04:16:39 Booleanos
- 04:24:49 Caracteres e Texto
- 04:32:05 Automático
- 04:38:06 Atribuições
- 04:45:42 Resumo de variáveis e tipos de dados
Capítulo 4: Operações em dados
- 04:46:45 Operações na introdução de dados
- 04:47:31 Operações Básicas
- 04:58:01 Precedência e Associatividade
- 05:12:06 Prefixo e Posfixo + & -
- 05:23:22 Operadores compostos
- 05:31:43 Operadores Relacionais: Comparando Coisas
- 05:40:51 Operadores Lógicos
- 05:56:09 Formatação de saída
- 06:33:26 Limites Numéricos
- 06:41:10 Funções matemáticas
- 06:54:23 Tipos integrais estranhos
- 06:59:41 Operações no resumo de dados
- 07:01:58 Controle de Fluxo: Introdução à Programação Condicional
- 07:03:30 Se Declaração
- 07:20:49 Caso contrário
- 07:28:46 Interruptor
- 07:42:44 Operador Ternário
- 07:52:20 Controle de Fluxo: Resumo da Programação Condicional Capítulo 6: Loops
- 07:53:49 Introdução aos Loops
- 07:55:20 For Loop
- 08:25:20 Loop Enquanto
- 08:36:54 Fazer loop while
- 08:47:08 Introdução aos Arrays
- 08:48:45 Declarando e Usando Arrays
- 09:15:53 Tamanho de uma matriz
- 09:26:44 Matrizes de caracteres
- 09:46:46 Limites de uma matriz
- 09:53:23 Introdução aos ponteiros
- 09:56:03 Declarando e usando ponteiros
- 10:14:48 Ponteiro para Char
- 10:27:26 Mapa de memória do programa
- 10:36:30 Alocação Dinâmica de Memória
- 11:05:45 Ponteiros pendurados
- 11:24:15 Quando Novo Falha
- 11:38:00 Segurança do ponteiro nulo
- 11:45:18 Vazamentos de memória
- 11:55:44 Matrizes Dinâmicas
- 12:11:04 Referências Introdução
- 12:11:58 Declarando e usando referências
- 12:22:28 Comparando Referências com Ponteiros
- 12:37:25 Referências e Const
Capítulo 10: Manipulação de Personagem e Strings
- 12:44:29 Introdução à manipulação de caracteres e strings
- 12:46:24 Manipulação de Personagem
- 13:09:28 Manipulação de C-String
- 13:41:42 Concatenação e cópia de C-String
- 14:01:19 Apresentando std::string
- 14:03:38 Declarando e usando std::string
- 14:12:47 Uma Regra de Definição
- 14:28:25 Primeira mão nas funções
- 15:00:50 Declaração e Definição da Função
- 15:15:30 Funções em vários arquivos - Modelo de compilação revisitado
- 15:42:30 Passar por Valor
- 15:50:30 Passe de Ponteiro
- 15:57:46 Passagem por referência
Capítulo 12: Tirando coisas das funções
- 16:03:20 Tirando coisas das funções Introdução
- 16:03:58 Parâmetros de entrada e saída
- 16:17:54 Voltando das Funções
Capítulo 13: Sobrecarga de funções
- 16:49:00 Introdução às Funções do Lambda
- 16:49:38 Declarando e usando funções Lambda
- 17:20:25 Listas de Captura
- 17:34:24 Capture tudo no contexto
Capítulo 15: Modelos de funções
- 17:40:08 Introdução aos Modelos de Função
- 17:41:45 Experimentando Modelos de Função
- 18:19:52 Dedução de tipo de modelo e argumentos explícitos
- 18:35:47 Parâmetros de tipo de modelo por referência
- 18:48:55 Especialização em Modelo
Capítulo 16: Conceitos
- 19:04:31 Conceitos Introdução
- 19:06:47 Conceitos
- 19:25:32 Conceitos: Construindo o Seu Próprio
- 19:42:45 Requer Cláusula: Zoom In
- 19:59:53 Combinações Lógicas de Conceitos
- 20:09:39 Conceitos e Auto
Capítulo 17: Aulas
- 20:15:40 Introdução às Aulas
- 20:16:33 Sua primeira aula de C++
- 20:38:03 Construtores
- 20:53:35 Construtores padrão
- 20:59:42 Levantadores e Pegadores
- 21:10:06 Classe em vários arquivos
- 21:30:49 Gerenciando Objetos de Classe Através de Ponteiros
- 21:42:48 Destruidores
- 22:05:44 Ordem de Chamada do Construtor e Destruidor
- 22:11:03 O Este Ponteiro
- 22:33:33 Estrutura
- 22:42:37 Tamanho dos Objetos de Classe
Capítulo 18: Herança
- 22:52:43 Introdução à Herança
- 22:55:59 Sua primeira tentativa de herança
- 23:21:10 Membros Protegidos
- 23:32:06 Especificadores de Acesso à Classe Base: Ampliando
- 23:36:49 Especificadores de acesso de classe base: uma demonstração
- 24:07:42 Fechando a Herança Privada
- 24:26:36 Ressuscitando membros de volta ao escopo
- 24:46:59 Construtores Arg Padrão com Herança
- 24:57:37 Construtores personalizados com herança
- 25:26:56 Copiar construtores com herança
- 25:51:53 Herdando Construtores de Base
- 26:06:00 Herança com Destruidores
- 26:12:20 Símbolos reutilizados na herança
Capítulo 19: Polimorfismo
- 26:21:03 Introdução ao Polimorfismo
- 26:26:54 Vinculação estática com herança
- 26:55:24 Polimorfismo (ligação dinâmica) com funções virtuais
- 27:14:31 Tamanho de objetos polimórficos e fatiamento
- 27:26:37 Objetos Polimórficos Armazenados em Coleções
- 27:45:42 Substituição
- 27:52:45 Sobrecarregando, Substituindo e Escondendo
- 28:07:35 Herança e polimorfismo em diferentes níveis
- 28:33:03 Herança e polimorfismo com membros estáticos
- 28h49min13 Final
- 29:07:42 Funções virtuais com argumentos padrão
- 29:23:18 Destruidores Virtuais
- 29:35:38 Dynamic_cast<>()
- 30:08:17 Não chame funções virtuais (polimórficas) de construtores e destruidores
- 30:24:45 Funções virtuais puras e classes abstratas
- 30:43:37 Classes abstratas como interfaces
- 2022.02.17
- www.youtube.com
Curso de Estruturas de Dados Fácil a Avançado - Tutorial Completo de um Engenheiro do Google (partes 1-4)
Estruturas de dados Curso fácil a avançado - Tutorial completo de um engenheiro do Google
Sumário breve:
00:00:00 - 01:00:00 O instrutor explica as estruturas de dados e sua importância na criação de algoritmos mais rápidos e poderosos. O tutorial cobre a notação Big O e como ela é usada para padronizar quanto tempo e espaço um algoritmo requer, e exemplos concretos são fornecidos para diferentes complexidades de tempo. O tutorial também aborda a implementação de arrays estáticos e dinâmicos, incluindo suas vantagens e desvantagens, e se aprofunda na criação e inserção de nós em listas vinculadas simples e duplamente. Por fim, o tutorial fornece uma introdução à estrutura de dados da pilha e explica brevemente suas operações principais.
01:00:00 - 02:00:00 Esta seção do tutorial "Curso de Estruturas de Dados de Fácil a Avançado" fornece cobertura abrangente de várias estruturas de dados e suas funcionalidades. O tutorial orienta o público sobre os princípios de funcionamento de pilhas e filas, suas implementações usando arrays e listas encadeadas e sua importância em diferentes aplicativos, incluindo travessia de grafos e gerenciamento de solicitações de servidor. O tutorial também explora filas de prioridade e sua implementação usando heaps, esclarecendo a diferença entre filas de prioridade e heaps, bem como os tipos de heaps. O tutorial termina fornecendo uma demonstração passo a passo de como adicionar e remover elementos de um heap binário.
02:00:00 - 03:00:00 O engenheiro do Google apresenta um tutorial completo sobre estruturas de dados, explicando como remover nós de uma estrutura de dados de heap binário, como manter a invariante de heap em uma fila de prioridade e como nadar e nós coletores em uma estrutura de dados heap binário. O vídeo também cobre a estrutura de dados union find, que é usada para rastrear elementos divididos em conjuntos disjuntos e para mesclar dois grupos, com um exemplo sobre ímãs para ilustrar como a estrutura de dados funciona. Além disso, o algoritmo de Kruskal para encontrar uma árvore geradora mínima em um grafo é explicado e o conceito de compactação de caminho é introduzido para tornar a estrutura de dados de localização de união mais eficiente.
03:00:00 - 04:00:00 Este tutorial cobre várias estruturas de dados, começando com a estrutura de dados union-find e seus métodos, incluindo find, connected, parent, size e unify. O tutorial então passa para as árvores, incluindo definições para árvores, árvores enraizadas, árvores binárias e árvores de pesquisa binária. O vídeo fornece exemplos de inserção e remoção de nós de árvores de pesquisa binária, bem como diferentes algoritmos de travessia, incluindo pré-ordem, em ordem, pós-ordem e ordem de nível, e explica como implementar essas construções em Python e Java. Além disso, o vídeo apresenta tabelas de hash e discute a importância das funções de hash e métodos populares de resolução de colisão.
04:00:00 - 05:00:00 A seção aborda vários aspectos das tabelas hash e sua implementação. Ele discute a importância das funções de hash, que mapeiam chaves para valores e como lidar com colisões de hash usando técnicas como encadeamento separado e endereçamento aberto. O tutorial também aborda métodos para inserir, remover e pesquisar entradas em tabelas de hash, bem como redimensionar e gerenciar fatores de carga. O palestrante enfatiza a importância de escolher uma função de sondagem e tamanho de mesa apropriados para evitar loops infinitos e problemas de desempenho. Exemplos práticos são usados ao longo do tutorial para ilustrar os conceitos.
05:00:00 - 06:00:00 Esta seção fornece uma visão geral abrangente de tabelas de hash, hashing duplo e sondagem quadrática na resolução de colisão. O vídeo aborda os conceitos de redimensionamento e crescimento de uma tabela de hash, manipulação de colisões e exclusão e implementação de tabelas de hash usando sondagem quadrática. O vídeo também apresenta a árvore Fenwick, uma estrutura de dados que oferece suporte a consultas de intervalo e atualizações de ponto em tempo logarítmico com tempo de construção linear. O vídeo fornece uma explicação passo a passo de como executar somas de prefixo e consultas de intervalo usando a árvore Fenwick.
06:00:00 - 07:00:00 O tutorial em vídeo abrange vários tópicos, incluindo o conceito de uma árvore Fenwick para consultas rápidas de intervalo e atualizações de pontos, usando matrizes de sufixo e matriz LCP para localizar substrings exclusivas e substrings comuns mais longas e resolver o problema de substring comum mais longo usando uma técnica de janela deslizante. O tutorial também explica como encontrar a substring repetida mais longa de forma eficiente usando a matriz LCP e explora as propriedades e a importância de árvores de busca binária balanceadas, especificamente árvores AVL, e como elas podem ser mantidas balanceadas usando rotações de árvore. O vídeo fornece explicações detalhadas, exemplos e código-fonte em Java disponível no GitHub.
Parte 1
- 00:00:00 O palestrante apresenta o conceito de estruturas de dados como forma de organizar os dados de forma eficiente e como elas são essenciais na criação de algoritmos mais rápidos e poderosos. O palestrante fala sobre a importância de entender como e quando usar a estrutura de dados apropriada para a tarefa em questão e como as estruturas de dados podem tornar o código mais limpo e fácil de entender. O conceito de tipo de dados abstrato também é explicado junto com exemplos de como um tipo de dados abstrato fornece apenas a interface e não os detalhes específicos sobre como a estrutura de dados deve ser implementada. Além disso, o vídeo aborda brevemente a complexidade computacional para entender o desempenho das estruturas de dados.
- 00:05:00 O conceito de notação Big O é introduzido como uma forma de padronizar quanto tempo e espaço é necessário para que um algoritmo seja executado com base no pior arranjo possível de entrada. Big O só se preocupa com o que acontece quando as entradas se tornam muito grandes e remove valores constantes adicionados à notação de big O. O conceito de uma função f também é introduzido, e é declarado Big O de f de n é apenas n ao cubo, que é o maior e mais dominante termo nessa função.
- 00:10:00 O Google Engineer fornece exemplos concretos de como a notação Big O é usada. Os exemplos são categorizados com base em suas complexidades de tempo — tempo constante, tempo linear, tempo quadrático, tempo logarítmico. Ele também fornece uma análise passo a passo de como uma complexidade de tempo logarítmica é alcançada usando o exemplo de pesquisa binária. Além disso, ele demonstra como calcular a complexidade de tempo de um algoritmo mais complicado e explica a regra para determinar a complexidade de um algoritmo.
- 00:15:00 O palestrante discute a análise de complexidade de um loop aninhado com um loop externo e um loop interno. O loop interno tem uma quantidade constante de trabalho e o loop externo tem uma quantidade variável de trabalho. O grande O da função é O(n^4) pois n^3 é o termo dominante. O locutor então apresenta matrizes estáticas, que são contêineres de comprimento fixo contendo elementos indexáveis que são blocos contíguos de memória. Matrizes estáticas são usadas em todos os lugares, desde o armazenamento temporário de objetos até o armazenamento de informações de um fluxo de entrada ou saída. O palestrante descreve a estrutura básica de uma matriz, operações comuns que podem ser executadas nelas e sua análise de complexidade.
- 00:20:00 O instrutor discute o uso de arrays na programação, inclusive como solução alternativa para linguagens que permitem apenas um valor de retorno e na programação dinâmica. Ele explica que os arrays têm tempo de acesso constante devido à sua propriedade indexável, mas a pesquisa pode levar até um tempo linear no pior cenário. Inserção, anexação e exclusão de uma matriz estática não são possíveis, mas com uma matriz dinâmica, redimensionar a matriz interna para anexar resulta em uma operação de tempo rara, mas constante. Por fim, ele observa que os elementos podem ser iterados usando um loop for-each e que a indexação de array na ciência da computação começa em zero, o que pode ser confuso para alguns iniciantes.
- 00:25:00 O vídeo discute o conceito de indexação em arrays, onde um colchete denota a indexação, e como arrays dinâmicos podem crescer e encolher conforme necessário, permitindo operações semelhantes de get set como arrays estáticos. Para implementar uma matriz dinâmica, uma matriz estática é usada e, quando a capacidade é excedida, o tamanho da matriz é dobrado e todos os elementos são copiados para a nova matriz estática. O vídeo também mostra o código-fonte da classe array, que oferece suporte a genéricos do tipo T e possui variáveis de instância para array estático interno, comprimento e capacidade.
- 00:30:00 O instrutor passa pela implementação de vários métodos para uma matriz dinâmica, incluindo tamanho, inserção, limpeza, adição, remoção, índice de, contém e toString. O método add envolve redimensionar o array dobrando seu tamanho quando a capacidade é atingida, e o método remove usa dois índices para copiar todos os elementos do array, exceto o índice de remoção. O instrutor também demonstra como criar um iterador para a matriz dinâmica e fala sobre os benefícios de usar um iterador para iterar os elementos de uma matriz. No geral, o tutorial fornece uma introdução simples, porém abrangente, à implementação de arrays dinâmicos.
- 00:35:00 O instrutor fornece uma introdução às listas vinculadas simples e duplamente, explicando que elas são uma lista sequencial de nós que armazenam dados e apontam para outros nós que contêm dados. As listas vinculadas são usadas na implementação de listas, pilhas e filas, bem como listas circulares, encadeamento separado de tabelas hash e para listas e gráficos de adjacência. O instrutor também cobre alguma terminologia útil para criar listas encadeadas. Além disso, são discutidas as vantagens e desvantagens das listas encadeadas simples e duplamente, com as listas encadeadas simples sendo mais eficientes em termos de memória, mas sem a capacidade de acessar elementos anteriores, enquanto as listas encadeadas duplamente podem ser percorridas para trás e permitir a fácil remoção de um nó.
- 00:40:00 O instrutor explica os detalhes de implementação da criação e inserção de nós em uma lista de encadeamento simples e em uma lista de encadeamento duplo. Para inserir um nó em uma lista encadeada individualmente, um novo ponteiro é criado e o ponteiro transversal é avançado para a posição desejada, após o que o novo nó é criado e vinculado aos outros nós. Por outro lado, uma lista duplamente vinculada possui ponteiros para o próximo e para o anterior e, ao inserir um novo nó, os ponteiros dos nós adjacentes e do novo nó precisam ser atualizados. A remoção de um nó de uma lista vinculada individualmente envolve o uso de dois ponteiros para avançar e remover o nó desejado e, em seguida, desalocar sua memória posteriormente.
- 00:45:00 O palestrante aborda como remover nós de uma lista duplamente vinculada, o que é mais fácil do que remover nós de uma lista vinculada individualmente, pois não precisamos manter manualmente as referências ao último nó. O palestrante mostra uma implementação em Java e discute a complexidade de várias operações em listas encadeadas, como pesquisar e remover elementos da cabeça ou da cauda. Embora a pesquisa em uma lista encadeada seja linear no pior cenário, inserir ou remover o cabeçalho é um tempo constante. A remoção da cauda leva tempo linear em uma lista encadeada simples, mas não em uma lista duplamente encadeada porque tem uma referência ao nó anterior.
- 00:50:00 Nesta seção do vídeo, o apresentador explica a implementação de uma lista duplamente encadeada com métodos para limpar a lista, obter tamanho e verificar se está vazia e adicionar nós ao início e ao fim da lista. Ele também explica como espiar o primeiro ou o último elemento da lista, remover o primeiro ou o último elemento e remover um nó arbitrário no meio da lista. O apresentador enfatiza a importância de desalocar a memória corretamente e define a classe do nó como privada para impedir que os usuários a acessem diretamente.
- 00:55:00 Nesta seção do vídeo, o tutor explica como remover um nó de um determinado índice de uma lista encadeada, mesmo que os nós não estejam explicitamente indexados. O método Remove oferece suporte à remoção de um valor arbitrário da lista vinculada e à pesquisa de valores nulos. O tutor também explica o índice do método para obter o índice de um objeto dentro de uma lista encadeada e o método iterador. Por fim, o tutor apresenta a estrutura de dados da pilha e fornece brevemente uma visão geral de suas operações primárias, push e pop. O tutor também destaca que os próximos vídeos da série abordarão a implementação de pilha, problemas resolvidos usando pilhas e a complexidade de tempo associada às operações de pilha.
Parte 2
- 01:00:00 O vídeo discute como funciona uma pilha de estrutura de dados e seus vários usos na programação. O vídeo fornece um exemplo detalhado de como as operações são adicionadas e removidas de uma pilha e explica como as pilhas são usadas em editores de texto, compiladores e suporte à recursão. Além disso, o vídeo destaca como uma pilha pode ser usada para realizar uma pesquisa em profundidade em um gráfico e apresenta um exemplo interessante de problema de como determinar se uma sequência de colchetes é válida ou não usando uma pilha. Por fim, o vídeo inclui uma análise de complexidade das pilhas e como elas funcionam como uma lista encadeada.
- 01:05:00 O engenheiro do Google demonstra como verificar se uma sequência de colchetes é válida usando uma estrutura de dados de pilha. Ele percorre o algoritmo passo a passo, colocando colchetes esquerdos na pilha e retirando-os ao encontrar colchetes direitos, e verifica se eles combinam. Ele também explica como o jogo Tower of Hanoi pode ser relacionado a pilhas, já que cada pino representa uma pilha e os discos representam elementos que só podem ser movidos sob certas condições. Por fim, ele discute como as pilhas podem ser implementadas usando matrizes ou listas encadeadas.
- 01:10:00 Aprendemos sobre a criação de uma pilha usando uma lista vinculada individualmente e extraindo elementos da pilha em uma implementação simples de uma estrutura de dados de pilha na linguagem de programação Java. A pilha é criada apontando a cabeça para um nó nulo, o que significa que a pilha está vazia. Novos elementos são inseridos antes da cabeça, e o popping de elementos é feito movendo o ponteiro da cabeça para o próximo nó e desalocando o último nó. Vazamentos de memória em estruturas de dados podem causar problemas, por isso é importante estar atento a eles em todas as estruturas de dados e corrigi-los quando necessário.
- 01:15:00 O instrutor discute filas, uma estrutura de dados linear usada para modelar uma fila do mundo real com duas operações principais: enfileiramento e desenfileiramento. A frente e o verso da fila são usados para inserir e remover elementos, respectivamente. O instrutor também explica as várias terminologias relacionadas às filas, com o enfileiramento às vezes chamado de adição e o desenfileiramento como pesquisa ou remoção do início da fila. Um exemplo clássico de fila é uma fila em um cinema ou restaurante, e as filas podem ser úteis para acompanhar os x elementos mais recentes em uma sequência.
- 01:20:00 O vídeo explica como as filas são usadas para gerenciar as solicitações do servidor e conduzir uma primeira travessia de pesquisa ampla em um grafo. O conceito de enfileiramento de solicitações é introduzido, onde um servidor ocioso pode lidar apenas com um certo número de solicitações por vez e qualquer solicitação em excesso é colocada em uma fila. O vídeo também aborda os fundamentos da primeira pesquisa em largura, na qual os nós de um grafo são visitados em ordem de distância de um nó inicial. O vídeo termina explicando a implementação de elementos n-enfileiramento e desenfileiramento usando uma estrutura de dados de fila.
- 01:25:00 O tutorial se aprofunda nas filas e explica como o tipo de dados abstrato da fila pode ser implementado usando matrizes ou diferentes tipos de listas encadeadas - listas encadeadas individualmente e listas encadeadas duplamente. O tutorial fornece um exemplo de como a implementação de lista encadeada individualmente de uma fila pode funcionar e também discute a implementação de vários métodos de fila como pico, pesquisa e oferta usando a linguagem de programação Java. O tutorial também compartilha um link para o código-fonte da implementação da fila em github.com.
- 01:30:00 Nesta seção do tutorial, o Google Engineer explica o conceito e a implementação de estruturas de dados, especificamente filas e filas de prioridade. Ele discute como uma fila de prioridade opera de maneira semelhante a uma fila normal, com a única diferença de que cada elemento tem uma certa prioridade e os elementos com maior prioridade saem primeiro da fila. Ele também enfatiza que as filas de prioridade suportam apenas elementos comparáveis, o que significa que os dados que inserimos na fila de prioridade devem ser ordenados. Além disso, ele fornece um exemplo para explicar as operações de polling e adição de elementos em uma fila de prioridade. Nas próximas seções do tutorial, ele entrará em mais detalhes sobre as operações comuns realizadas em filas de prioridade, transformando filas de prioridade mínima em filas de prioridade máxima, análise de complexidade e formas de implementar filas de prioridade.
- 01:35:00 O engenheiro do Google explica como as filas de prioridade são implementadas usando heaps. Um heap é uma estrutura de dados baseada em árvore que satisfaz a invariante do heap, o que significa que o valor do nó pai é sempre maior ou igual ao valor do nó filho para todos os nós, resultando em dois tipos de heaps: Max heaps e pilhas mínimas. Heaps são importantes porque formam a estrutura de dados subjacente canônica para filas de prioridade. O engenheiro do Google então mostra exemplos de estruturas e pergunta ao público se são heaps ou não, demonstrando que todos os heaps devem ser árvores e satisfazer a invariante do heap.
- 01:40:00 A importância das filas de prioridade em algoritmos como o algoritmo de caminho mais curto de Dijkstra e a codificação de Huffman é discutida. As filas de prioridade são úteis em situações em que há necessidade de buscar dinamicamente o próximo melhor ou pior elemento. O foco principal está nas filas de prioridade implementadas como heaps binários e nas operações, incluindo adicionar um elemento, remover um elemento, verificar a contenção e alterar filas de prioridade mínima para filas de prioridade máxima. Tabelas hash podem ser usadas para melhorar a complexidade do tempo de remoção para ser logarítmica, enquanto uma varredura linear é realizada para todos os elementos para o método ingênuo. A seção termina com um truque para converter filas de prioridade mínima em filas de prioridade máxima.
- 01:45:00 O engenheiro do Google explica como usar a negação como uma forma simples de implementar heaps reversos em filas de prioridade. Ele fornece exemplos de manipulação numérica e de string usando uma fila de prioridade mínima com o comparador lexicográfico padrão, bem como um comparador negado. O engenheiro também apresenta o conceito de heaps binários e como adicionar elementos a eles.
- 01:50:00 O instrutor explica a terminologia e os conceitos importantes necessários para entender como adicionar elementos efetivamente a uma fila de prioridade usando um heap binário. Ele esclarece que uma fila de prioridade não é um heap, mas um tipo de dado abstrato que define o comportamento que uma fila de prioridade deve ter, e que os heaps são apenas a estrutura de dados que nos permite realmente implementar esse comportamento. Ele também discute os tipos de heaps, incluindo heaps binários, e explica a propriedade de árvore binária completa e como representar um heap binário usando uma construção de matriz.
- 01:55:00 O engenheiro do Google explica como adicionar nós a um heap binário e manter o heap invariante usando uma técnica para acessar facilmente os filhos e os pais de um nó. Eles ilustram com o exemplo de inserção de valores em um heap mínimo e demonstram como borbulhar os nós para satisfazer a invariante do heap. Na próxima seção, o engenheiro aborda a remoção de elementos de um heap binário e enfatiza a importância de remover o valor raiz, que é o nó de interesse com a prioridade mais alta.
Parte 3
- 02:00:00 O engenheiro do Google explica o processo de remoção de nós de uma estrutura de dados heap binário usando o método pull. O pull é feito em dois casos, ao remover o nó raiz e ao remover um nó específico. Ao remover o nó raiz, o nó é trocado pelo último nó na matriz, e a invariante do heap é assegurada por meio do bubbling down. Ao remover um nó específico, o nó é procurado linearmente, trocado com o último nó na pilha e, em seguida, a invariante da pilha é assegurada por meio de bolhas para cima ou para baixo, dependendo do valor do nó trocado. O engenheiro conclui que a extração leva um tempo logarítmico para o nó raiz e um tempo linear para um nó específico.
- 02:05:00 Nesta seção do tutorial, o engenheiro do Google explica como remover nós em um heap com complexidade de tempo aprimorada usando uma tabela de hash. Em vez de fazer uma varredura linear para localizar o índice do nó a ser removido, cada nó é mapeado para o índice em que foi encontrado. Quando queremos remover um determinado nó, basta procurar seu índice para começar a fazê-lo. O vídeo também aborda como lidar com o problema de valores múltiplos no heap e como acompanhar as posições dos valores na árvore. O Engenheiro explica que, desde que satisfaçamos a invariante do heap, não importa qual nó removemos. O tutorial inclui exemplos de adição, extração e remoção de elementos com o novo esquema proposto.
- 02:10:00 O palestrante explica como inserir, remover e manter o heap invariante em uma fila de prioridade usando uma estrutura de dados heap. Em seguida, ele mergulha no código-fonte e destaca algumas variáveis de instância importantes e construtores necessários para implementar a fila de prioridade. Ele explica que os elementos permitidos na fila de prioridade devem implementar a interface comparável e que o registro e as remoções podem ser rastreados usando um mapa que mapeia um elemento para um conjunto de inteiros que representam as posições do elemento no heap.
- 02:15:00 Nesta seção do tutorial, o Google Engineer discute diferentes maneiras de criar uma fila de prioridade, incluindo criar uma fila inicialmente vazia com uma capacidade definida, criar uma fila com uma capacidade inicial definida e construir uma fila em linear tempo usando a operação heapify. O engenheiro também examina alguns métodos simples de uma fila de prioridade, incluindo empty, clear, size, peek, poll e contains. O método add também é discutido, com detalhes sobre como adicionar elementos à fila e a importância de acompanhar os elementos em um mapa. A função nadar também é destacada como uma etapa necessária após adicionar um elemento ao final da lista.
- 02:20:00 Nesta seção do vídeo, o engenheiro do Google explica os métodos para nadar e afundar nós em uma estrutura de dados heap binário. O método de natação envolve trocar nós com seu pai e mover para cima até que o nó esteja na posição correta com base em seu valor. O método de afundamento é semelhante, mas envolve comparar o nó com seus nós filhos e trocar com o menor até atingir a posição correta. O engenheiro também explica os métodos swap, remove e remove add implementados no heap binário. O método remove add envolve trocar o nó removido com o último elemento na pilha e afundar ou nadar o novo nó para a posição apropriada.
- 02:25:00 Nesta seção do tutorial, o instrutor explica como remover um nó de uma estrutura de dados heap e garantir que a integridade mínima do heap seja mantida usando um método para afundar ou nadar nós, dependendo se a troca afeta o heap ordem. A seção também apresenta a estrutura de dados union find e suas duas operações principais, find e union, que são usadas para rastrear elementos divididos em conjuntos disjuntos e para mesclar dois grupos, respectivamente.
- 02:30:00 O palestrante usa o exemplo dos ímãs para explicar como funciona a estrutura de dados union find. A localização de união mescla itens ou grupos de itens com eficiência, atribuindo-lhes uma cor arbitrária. A estrutura de dados de localização de união é usada em vários algoritmos, como o algoritmo de árvore abrangente mínima e percolação de grade. O union find possui excelente complexidade e sua construção é linear em tempo, enquanto sua função de contagem de componentes pode determinar o número de componentes em tempo constante, tornando-o uma ótima estrutura de dados para se ter por perto.
- 02:35:00 Nesta seção do tutorial, o engenheiro do Google explica o algoritmo de Kruskal para encontrar uma árvore geradora mínima em um grafo. O algoritmo envolve a classificação de arestas pelo peso ascendente da aresta e, em seguida, unifica os nós que não pertencem ao mesmo grupo, até que todos os vértices sejam unificados em um grupo. A estrutura de dados de localização de união é usada para mesclar grupos de forma eficiente e evitar ciclos. O engenheiro fornece um gráfico de exemplo e percorre as etapas do algoritmo para ilustrar como ele funciona.
- 02:40:00 O tutorial explica a estrutura de dados union find e como ela funciona internamente. O primeiro passo é criar um mapeamento entre os objetos e os inteiros no intervalo de zero a N não inclusivo, onde N é o número de elementos. Então um array é construído, e cada índice tem um objeto associado, o que é feito através do mapeamento. O valor na posição da matriz é inicialmente o índice em que está e cada nó é um nó raiz mapeado para si mesmo. À medida que as instruções são executadas para unificar objetos em grupos, os valores na matriz são alterados para mapear para outros objetos. Componentes menores são mesclados em componentes maiores e os nós raiz são usados para unificar grupos.
- 02:45:00 O palestrante fala sobre como mesclar elementos em diferentes grupos usando a estrutura de dados union find. Ao localizar e seguir os nós pais do nó raiz de cada componente, podemos determinar a qual componente um elemento pertence. Para unificar dois componentes, fazemos com que um dos nós raiz aponte para se tornar o pai da outra raiz. O número de componentes é igual ao número de nós raiz restantes, e o número de nós raiz diminui apenas à medida que unificamos os componentes. O palestrante também observa que a implementação dessa estrutura atualmente não possui uma complexidade de tempo amortizada sem o uso de compactação de caminho, uma otimização a ser discutida no próximo vídeo.
- 02:50:00 O conceito de compactação de caminho é apresentado para mostrar como torna a estrutura de dados de localização de união mais eficiente. A compactação de caminho envolve a compactação de todos os nós ao longo do caminho para o nó raiz, permitindo assim uma pesquisa de tempo constante do nó raiz para qualquer componente determinado. O exemplo de unificação de grupos com e sem compressão de caminho é dado para comparar e contrastar os dois métodos, demonstrando a eficiência obtida com a compressão de caminho.
- 02:55:00 O instrutor discute como a compactação de caminho e a união funcionam juntas para criar uma estrutura de dados eficiente. Ele demonstra como a compactação de caminho comprime dinamicamente os caminhos ao longo do caminho até atingir um estado final. O código union find é apresentado no vídeo, com explicações sobre o uso de arrays para indexação e rastreamento de relacionamentos pai-filho. Além disso, o código inclui métodos para verificar o nó raiz e compactar o caminho para ele. O instrutor enfatiza a importância de assistir a outros vídeos sobre localização de união para obter uma compreensão completa do assunto.
Parte 4
- 03:00:00 O instrutor apresenta uma estrutura de dados union-find e seus métodos, incluindo find, connected, parent, size e unify. Ele demonstra como os nós raiz da estrutura contêm o tamanho de cada componente conectado, e o método unify mescla grupos menores em grupos maiores. Passando para as árvores, o instrutor dá uma breve visão geral das árvores como grafos não direcionados e apresenta as árvores binárias e as árvores binárias de busca. Ele promete cobrir como inserir e remover nós em árvores de busca binária, percursos de árvore e como eles podem ser aplicados a árvores gerais em tutoriais posteriores.
- 03:05:00 O conceito de árvores é introduzido, com várias definições fornecidas. Uma árvore pode ser definida como um grafo não direcionado que é conectado e acíclico, como um grafo com n nós e n-1 arestas ou como um grafo em que existe apenas um caminho entre quaisquer dois vértices. Uma árvore enraizada também é introduzida, onde qualquer nó pode se tornar a raiz e os nós filho e pai são definidos. O pai do nó raiz é ele mesmo e os nós folha são definidos como nós sem filhos. O conceito de uma subárvore também é introduzido, denotado por triângulos dentro de uma árvore. Além disso, a definição de uma árvore binária é explicada como uma árvore na qual cada nó tem no máximo dois filhos.
- 03:10:00 O vídeo aborda as árvores binárias de busca, que são árvores binárias que satisfazem a invariante da árvore binária de busca. Isso significa que a subárvore esquerda sempre possui valores menores que o nó atual e a subárvore direita possui valores maiores. O vídeo apresenta vários exemplos de árvores de pesquisa binária e desafia os espectadores a determinar se elas satisfazem a invariante. Árvores de busca binária são úteis em muitas implementações de tipos de dados abstratos e são usadas em árvores de busca binária balanceada e árvores de sintaxe. Eles também têm uma complexidade de tempo logarítmica no caso médio para operações como inserção e pesquisa em dados aleatórios.
- 03:15:00 Nesta seção do tutorial, o engenheiro do Google discute as árvores de busca binárias e como inserir elementos nelas. As árvores binárias de busca têm comportamento logarítmico em média, o que as torna fáceis de implementar e eficientes para a maioria dos casos. No entanto, no pior caso, uma árvore binária pode se tornar uma estrutura de dados linear, o que não é o ideal. Para inserir um elemento em uma árvore de pesquisa binária, o elemento deve ser comparável e um dos quatro casos pode ocorrer: recursar na subárvore esquerda, recursar na subárvore direita, lidar com valores duplicados ou inserir um novo nó. Por fim, o engenheiro demonstra a inserção de valores em uma árvore de pesquisa binária usando animações.
- 03:20:00 O engenheiro do Google explica o pior cenário ao inserir valores em uma árvore de busca binária, o que faz com que ela se torne uma estrutura linear. Esse comportamento é indesejável porque torna mais lentas as operações, como procurar nós ou excluir valores. O engenheiro então explica como remover elementos de uma árvore de pesquisa binária em duas etapas: primeiro encontrando o nó a ser removido e, em seguida, substituindo-o por seu sucessor para manter a invariante da árvore de pesquisa binária. O vídeo fornece um exemplo de como pesquisar valores em uma árvore de pesquisa binária para ajudar a entender o processo.
- 03:25:00 O engenheiro do Google explica os quatro casos da fase Remover ao lidar com uma árvore binária de busca. O primeiro caso é quando o nó a ser removido é um nó folha; o segundo e o terceiro casos ocorrem quando há apenas uma subárvore à esquerda ou à direita. O quarto caso ocorre quando o nó tem uma subárvore esquerda e uma direita, e a questão é em qual subárvore estará o sucessor do nó? A resposta é que o sucessor pode ser o maior valor na subárvore esquerda ou o menor valor na subárvore direita, e pode haver dois sucessores possíveis.
- 03:30:00 Nesta seção do curso, o instrutor explica como remover nós de árvores de busca binária usando o conceito de um nó sucessor. O sucessor é o menor nó da subárvore direita ou o maior nó da subárvore esquerda. O instrutor demonstra a remoção de nós por meio de vários exemplos, enfatizando a importância de reequilibrar a árvore após a remoção. A seção termina com uma visão geral de diferentes percursos de árvore, incluindo pré-ordem, em ordem, pós-ordem e ordem de nível.
- 03:35:00 O instrutor explica os conceitos de percursos de pré-ordem, em ordem e pós-ordem em árvores binárias. Ele explica que a pré-ordem imprime o valor do nó atual seguido por suas subárvores esquerda e direita e, em seguida, fornece um exemplo de como a travessia de pré-ordem funciona em uma árvore binária, mantendo uma pilha de chamadas para rastrear quais nós são visitados. Da mesma forma, ele explica como funciona a travessia em ordem, que envolve percorrer a subárvore esquerda, imprimir o valor e, em seguida, percorrer a subárvore direita. O instrutor usa uma árvore de pesquisa binária como exemplo e destaca a ordem na qual os nós são visitados e impressos durante a travessia.
- 03:40:00 O tutorial discute diferentes algoritmos de passagem para árvores binárias. Primeiro, a travessia inorder, que imprime os valores dos nós em ordem crescente. Em seguida, a travessia de pós-ordem, que percorre a subárvore esquerda, depois a subárvore direita, e somente após ambas serem percorridas, imprime o valor do nó. O tutorial continua explicando a primeira pesquisa em amplitude e como ela pode ser usada para passagem de ordem de nível, que imprime os nós uma camada por vez. Uma fila é usada para rastrear os nós a serem explorados e os nós são adicionados à fila à medida que seus nós pais são visitados.
- 03:45:00 Nesta seção do vídeo, o instrutor explica como realizar uma pesquisa em largura usando uma estrutura de dados de fila. Ele demonstra o processo de explorar nós e adicionar seus filhos à fila de acordo com sua ordem. Ele enfatiza a importância de usar uma fila em vez de uma pilha ao executar a travessia de ordem de nível. O vídeo então muda o foco para a implementação de uma árvore de pesquisa binária em Java, com o instrutor explicando a estrutura da classe, as variáveis de instância e os métodos usados para adicionar elementos à árvore. Ele também destaca a importância de escolher um tipo comparável ao trabalhar com árvores de busca binárias.
- 03:50:00 O instrutor explica o processo de remoção de nós de uma árvore de busca binária. Eles começam discutindo o método público de remoção de nós e explicando que só removerão o nó se ele existir na árvore, que é verificada primeiro. Em seguida, eles se aprofundam no método recursivo usado para remover o nó, que envolve encontrar o nó a ser removido e, em seguida, removê-lo com base em se ele possui subárvores esquerda e/ou direita. O instrutor explica três casos diferentes de remoção, que envolvem uma subárvore esquerda ou direita ou ambas as subárvores esquerda e direita. Eles também fornecem métodos auxiliares para percorrer a árvore para encontrar o nó sucessor.
- 03:55:00 O engenheiro do Google explica como implementar uma árvore de pesquisa binária em Python, incluindo a inserção de um novo nó, a pesquisa de um elemento específico e o cálculo da altura da árvore. Ele também mostra como implementar percursos de árvore binária iterativamente usando um método personalizado chamado "traverse", que recebe uma ordem de percurso de árvore como entrada e retorna um iterador para esse pedido. Em seguida, ele apresenta tabelas de hash e discute a importância das funções de hash, bem como métodos populares de resolução de colisão, como encadeamento separado e endereçamento aberto.
- 2019.09.19
- www.youtube.com
Curso de Estruturas de Dados Fácil a Avançado - Tutorial Completo de um Engenheiro do Google (partes 5-8)
Estruturas de dados Curso fácil a avançado - Tutorial completo de um engenheiro do Google
Parte 5
- 04:00:00 O instrutor apresenta o conceito de tabelas de hash e sua implementação usando técnicas de hash. As tabelas hash são usadas para construir um mapeamento de chaves para valores, onde cada chave é única e está associada a um valor. Para mapear as chaves para valores, uma função hash é usada, que mapeia as chaves para um número inteiro em algum intervalo fixo. O instrutor mostra como definir funções de hash para objetos arbitrários, como strings, usando os valores ASCII de caracteres na string. As tabelas de hash costumam ser usadas para rastrear frequências de valores e construir mapeamentos entre pares chave-valor, desde que as chaves sejam hasháveis. A seção termina com um mini desafio para definir uma função hash para um banco de dados de pessoas com três campos.
- 04:05:00 O instrutor discute as funções de hash e suas propriedades. A função hash é definida arbitrariamente e pode ter um número infinito de possibilidades. O instrutor enfatiza que as funções de hash devem ser determinísticas para evitar estragar a tabela de hash. A uniformidade das funções de hash também é importante para minimizar as colisões de hash que ocorrem quando dois objetos têm o mesmo valor. O instrutor também ilustra como os valores de hash podem acelerar as comparações de objetos e continua explicando que funções de hash sofisticadas, como funções de hash criptográficas e somas de verificação, são usadas para arquivos em vez das funções de hash usadas para tabelas de hash.
- 04:10:00 O tutorial explica o que torna uma chave do tipo 't' hashable e como uma tabela hash funciona usando uma função hash uniforme para indexá-la. Ele menciona que as funções de hash precisam ser determinísticas e impor chaves imutáveis que são fixas e constantes, como strings e inteiros imutáveis. Ao usar a função hash como uma forma de indexar em uma tabela hash, podemos obter tempos rápidos de inserção, pesquisa e remoção em tempo constante. O tutorial também fornece um exemplo de inserção de pares chave-valor em uma tabela que eventualmente leva a uma colisão de hash e explica como lidar com colisões.
- 04:15:00 O palestrante discute técnicas de resolução de colisão de hash, especificamente encadeamento separado. O encadeamento separado é uma maneira de lidar com colisões de hash mantendo uma estrutura de dados auxiliar, geralmente uma lista encadeada, para manter todos os diferentes pares chave-valor que fazem hash para um valor específico. A complexidade de tempo de uma tabela de hash pode atingir inserção, remoção e pesquisa de tempo constante em média, mas com uma função de hash terrível que não é uniforme, pode ser um tempo linear. O palestrante também fornece um exemplo de como o encadeamento separado funciona e como podemos usá-lo para lidar com colisões em nossa tabela de hash, mantendo uma estrutura de dados de lista encadeada para cada índice na matriz.
- 04:20:00 O palestrante explica como as pesquisas funcionam em uma tabela hash com encadeamento separado, que usa listas encadeadas para lidar com colisões. Com uma determinada chave, o palestrante demonstra como encontrar o valor correspondente fazendo hash da chave e pesquisando a lista encadeada no balde correspondente da tabela de hash. O palestrante também aborda algumas questões comuns sobre como manter a complexidade de tempo constante, remover pares chave-valor e usar estruturas de dados diferentes para lidar com baldes na tabela de hash. Por fim, o palestrante compartilha algum código-fonte para uma implementação de tabela hash usando encadeamento separado.
- 04:25:00 O vídeo apresenta tabelas de hash e como elas são implementadas em Java. A classe de entrada é discutida primeiro, com foco em genéricos, códigos hash e método equals. A própria tabela de hash é explicada, incluindo variáveis de instância como fator de carga máximo, capacidade, limite e a própria tabela, que é uma matriz de listas vinculadas. Vários métodos como tamanho, vazio, claro, contém chave e hash também são discutidos junto com seus detalhes de implementação. Por fim, é explicado o método de índice normalizado, que é usado para converter um valor de hash em um índice para pesquisa na tabela de hash.
- 04:30:00 Nesta seção do vídeo, o palestrante explica os métodos envolvidos na implementação de uma tabela hash, como inserir, obter, remover, buscar entrada e redimensionar tabela. O método insert adiciona uma nova entrada à tabela hash ou atualiza uma já existente, enquanto get recupera o valor associado a uma chave específica. Remove remove o par de valores-chave da tabela de hash e o método de entrada de busca ajuda a localizar a entrada em um determinado índice de bucket. Por fim, redimensionar tabela redimensiona a tabela dobrando sua capacidade e, em seguida, cria uma nova tabela com a nova capacidade, move os dados da tabela antiga para a nova tabela e remove os dados antigos.
- 04:35:00 O instrutor discute a técnica de endereçamento aberto para resolver colisões em tabelas hash. Este método armazena os pares chave-valor na própria tabela em vez de uma estrutura de dados auxiliar. Portanto, é crucial gerenciar o tamanho da tabela de hash e o número de elementos nela. O fator de carga, que é a proporção de itens para o tamanho da mesa, precisa ser mantido abaixo de um certo limite para evitar que se torne exponencialmente ruim. Ao inserir uma nova chave, a função hash fornece uma posição original para a chave, mas se houver uma colisão, uma sequência de sondagem é usada para encontrar o próximo ponto aberto. A sequência de sondagem linear é uma das muitas para escolher.
- 04:40:00 O instrutor discute o endereçamento aberto, um método de lidar com colisões em tabelas de hash em que o item é colocado em um local diferente quando o índice de hash original já está ocupado. Várias funções de sondagem são introduzidas, como sondagem linear, sondagem quadrática, hashing duplo e função de sondagem de gerador de números pseudo-aleatórios, cada uma das quais usa uma fórmula matemática diferente para encontrar o próximo slot. No entanto, a principal dificuldade com o endereçamento aberto é o potencial de produzir ciclos menores que o tamanho da tabela de hash, o que pode levar a um loop infinito. Um exemplo prático é dado para ilustrar este problema.
- 04:45:00 O palestrante discute a questão dos ciclos nas funções de sondagem usadas nas tabelas hash e como lidar com isso. O palestrante explica que técnicas como sondagem linear, sondagem quadrática e hash duplo estão todas sujeitas a essa questão de ciclos, mas podem ser redefinidas para produzir um ciclo de comprimento para evitar ficar preso em um loop infinito ao inserir um elemento. A constante "b" na sondagem linear é considerada obsoleta, e o palestrante menciona que algumas funções lineares podem ser incapazes de produzir um ciclo completo de ordem "n". A solução para esse problema é escolher funções de sondagem que produzam um ciclo de exatamente "n", certificando-se de que a constante "a" e o tamanho da tabela "n" sejam relativamente primos entre si.
- 04:50:00 O instrutor discute as tabelas de hash e como elas funcionam, incluindo funções de sondagem, tamanho da tabela, fator de carga e redimensionamento. Ele usa um exemplo com sondagem linear para demonstrar como inserir pares de chave-valor em uma tabela de hash e evitar loops infinitos causados por colisões de hash. No entanto, ele ressalta que a escolha da função de sondagem e do tamanho da tabela pode impactar significativamente o desempenho, e selecionar uma função cujo maior denominador comum com o tamanho da tabela não seja um pode levar a ciclos e causar problemas.
- 04:55:00 Vemos um exemplo de uso de uma função de sondagem para inserir pares chave-valor em uma tabela hash sem colisões. Se ocorrer uma colisão, a função de sondagem continuará a sondar até que um ponto vazio seja encontrado para evitar a ocorrência de qualquer ciclo. Uma vez que o número de elementos excede o limite da tabela, o tamanho da tabela é dobrado, mantendo o GCD de N. Os elementos antigos são colocados na nova tabela usando o novo tamanho da tabela, mantendo a mesma função de sondagem. Por fim, um novo par chave-valor é inserido e, se o local estiver livre, não há problemas.
Parte 6
- 05:00:00 O instrutor discute a sondagem quadrática em tabelas hash, que é usada para lidar com colisões em endereçamento aberto. Isso envolve a sondagem de acordo com uma fórmula quadrática usando a seleção de uma função de sondagem aleatória. O instrutor explica que nem todas as funções quadráticas são viáveis porque não produzem um ciclo de ordem que resulta em ficar preso em um loop infinito, mas a maioria das funções quadráticas selecionadas aleatoriamente acabará produzindo um ciclo. O instrutor fornece três maneiras mais populares de selecionar uma função de sondagem e se concentra na segunda, em que p de x é igual a x ao quadrado mais x dividido por dois e o tamanho da tabela é uma potência de dois.
- 05:05:00 O palestrante discute o processo de inserção de elementos em tabelas hash usando o hashing duplo e a técnica de resolução de colisão de endereçamento aberto. Eles explicam a importância do tamanho da tabela ser uma potência de dois e como lidar com colisões usando sondagem. O alto-falante também demonstra o processo de redimensionamento da mesa quando o fator de carga excede um determinado limite. Eles discutem como atualizar os elementos existentes e como inserir novos na tabela.
- 05:10:00 O instrutor explica o conceito de double hashing, que é um método de sondagem usado para lidar com colisões em tabelas de hash. O esquema de hash duplo envolve sondar de acordo com um múltiplo constante de outra função hash, chamada de função hash secundária. O instrutor alerta sobre o problema dos ciclos infinitos que podem ocorrer no caso de double hashing e apresenta uma estratégia para corrigi-lo, que envolve escolher um número primo para o tamanho da tabela e construir um valor chamado delta. Ele também discute a maneira sistemática de gerar novas funções de hash para diferentes tipos de dados usando o mesmo bloco de construção fundamental.
- 05:15:00 O palestrante explica o conceito de funções hash e como elas podem ser combinadas para criar uma nova função hash. Eles mencionam o uso de funções hash universais e fornecem um exemplo usando hashing duplo. Eles discutem o processo de inserção de pares chave-valor em uma tabela de hash enquanto também lidam com colisões e atualizações de hash. O exemplo usa um tamanho de tabela de sete e um fator de carga máximo de 0,75, e a função hash usa inteiros e números reais como blocos de construção.
- 05:20:00 O tutorial explica o processo de redimensionamento e crescimento de uma tabela hash com hashing duplo, que envolve dobrar o tamanho da tabela, encontrar o próximo número primo acima desse valor, alocar uma nova tabela e inserir os elementos antigos na nova mesa. O tutorial fornece um exemplo em que a tabela original atingiu seu limite máximo após a inserção de cinco elementos e a tabela é redimensionada para um novo tamanho de 17. O tutorial também explora os problemas que surgem ao remover elementos de uma tabela hash usando o endereçamento aberto esquema e a importância de evitar colisões durante as operações de inserção e exclusão.
- 05:25:00 O vídeo explica como lidar com colisões de hash e exclusão em uma tabela de hash. O método ingênuo de exclusão, que simplesmente limpa o conteúdo do balde, mostra-se falho porque afeta a capacidade de encontrar elementos na tabela de hash corretamente. Em vez disso, o vídeo recomenda colocar um marcador exclusivo chamado lápide no lugar do elemento excluído. Este marcador pode ser posteriormente substituído por um novo par chave-valor ou removido durante o redimensionamento da tabela de hash. O vídeo fornece um exemplo usando sondagem quadrática para mostrar como as marcações para exclusão são usadas durante a pesquisa de tabela de hash.
- 05:30:00 O engenheiro do Google fornece uma visão geral das tabelas de hash que usam dois endereços abertos como um esquema de resolução de colisão. O engenheiro discute a exclusão preguiçosa ou a realocação lenta, que envolve a realocação de pares de valores-chave para evitar atingir várias lápides durante a sondagem. O engenheiro também fornece um passo a passo do código para uma tabela de hash que usa sondagem quadrática, que envolve o armazenamento de pares de valores-chave diretamente dentro de uma matriz, em vez de ter uma matriz com uma classe wrapper para uma entrada. O engenheiro explora o construtor e as constantes padrão para a tabela de hash, o que permite aos usuários inicializá-la sem nenhum parâmetro.
- 05:35:00 Nesta seção do curso, o instrutor explica a implementação da tabela hash usando sondagem quadrática. O método envolve calcular o limite, normalizar o índice e inicializar as tabelas. As informações do método de inserção são fornecidas onde os pares chave-valor são inseridos na tabela de hash ou atualizados se a chave já existir. O instrutor também discute a contagem de chaves, a verificação vazia da tabela de hash e a adição de put antes de passar para o método de inserção. O loop do-while para a inserção de uma chave é explicado em detalhes.
- 05:40:00 O instrutor explica os métodos contains key, has key, get e remove de uma implementação de tabela hash. Os métodos contains key e has key verificam se existe uma chave na tabela hash chamando o método get, que retorna um valor verdadeiro ou falso para o sinalizador contains. O método get localiza o índice de hash e procura a chave. Se a chave existir, o sinalizador contém será definido como verdadeiro e o valor será retornado. O método remove é mais simples, onde uma chave é encontrada primeiro na tabela de hash, depois decrementada e uma lápide é despejada em seu lugar. O método resize table é chamado quando novos elementos estão sendo inseridos para aumentar o tamanho da tabela, onde uma nova tabela é alocada e a tabela atual é trocada pela nova tabela para chamar o método insert.
- 05:45:00 A árvore Fenwick, também conhecida como árvore de índice binário, é apresentada como uma estrutura de dados para calcular com eficiência consultas de intervalo em uma matriz e executar atualizações de pontos. A motivação por trás da árvore Fenwick é a ineficiência das consultas lineares ao computar intervalos em uma matriz. Calculando todas as somas de prefixo para a matriz, as consultas de intervalo podem ser calculadas em tempo constante. No entanto, as atualizações no array exigem o recalculo de todas as somas de prefixo, tornando o processo ineficiente. A árvore de Fenwick foi criada para resolver esse problema, suportando consultas de intervalo e atualizações de pontos em tempo logarítmico com tempo de construção linear. A árvore de Fenwick funciona fazendo com que cada célula seja responsável por uma série de outras células com base no valor de seu bit menos significativo.
- 05:50:00 Nesta seção do vídeo, o instrutor discute as árvores Fenwick e como elas funcionam para consultas de alcance. Ele mostra um diagrama com uma matriz baseada em um e a representação binária de cada número. O diagrama mostra os bits menos significativos responsáveis por si mesmos e todas as outras células responsáveis por um intervalo de 2, 4, 8 ou 16 células. Para realizar uma consulta de intervalo, o instrutor explica como calcular a soma do prefixo até um determinado índice descendo em cascata até chegar a zero. Ele demonstra como encontrar a soma do prefixo para um índice específico e como fazer uma soma de intervalo entre dois índices fornecidos.
- 05:55:00 Aprendemos como calcular somas de prefixos usando um efeito cascata descendente e como executar um algoritmo de consulta de intervalo usando árvores Fenwick. O cálculo da soma do prefixo envolve começar em um determinado índice e subtrair o bit menos significativo do valor até chegar a zero e, em seguida, adicionar todos os valores durante cada subtração. O algoritmo de consulta de intervalo usa árvores de Fenwick, onde obtemos a diferença entre as somas de prefixo para consultas de intervalo. O algoritmo requer manipulação de bits e fornece um pequeno algoritmo para computação mais rápida. O autor do vídeo recomenda conferir o vídeo de consulta de intervalo de árvores Fenwick anterior para obter mais contexto sobre como a árvore é configurada e como as operações são executadas nela.
Parte 7
- 06:00:00 O conceito de atualização de pontos e construção da árvore Fenwick são explicados pelo Google Engineer. As atualizações de ponto envolvem a adição de valores à árvore em um índice específico e a localização das células responsáveis por esse intervalo de responsabilidade. Enquanto isso, a construção linear da árvore de Fenwick envolve a atualização da célula imediata responsável por um valor, propagando os valores por toda a árvore no local, resultando em uma árvore de Fenwick totalmente funcional. O processo de propagação depende da ideia em cascata de atualizar o pai responsável por um valor específico.
- 06:05:00 Nesta seção do tutorial, o conceito de uma árvore Fenwick é explicado em detalhes. Uma árvore Fenwick é uma estrutura de dados que é usada para executar rapidamente consultas de intervalo e atualizações de pontos em uma matriz de valores. A estrutura de dados utiliza um tipo de indexação binária em que cada célula é responsável por propagar seu valor para seu pai e assim por diante. O algoritmo de construção de uma árvore de Fenwick também é discutido, o que envolve transformar uma matriz de valores em uma árvore de Fenwick clonando a matriz original e calculando a célula pai para cada elemento na nova estrutura de árvore. O código-fonte para uma implementação de árvore Fenwick em Java é mostrado e está disponível em um repositório GitHub.
- 06:10:00 O instrutor explica como criar uma classe de árvore Fenwick e seus diferentes construtores. Ele também explica as somas de prefixos, que permitem calcular a soma de prefixos de um a i, inclusive. O vídeo também aborda como adicionar a partir de uma atualização de ponto e um método adicional para definir o índice igual a k. O instrutor enfatiza a importância do uso da manipulação binária e da estrutura de dados de matriz de sufixos, que é muito útil no processamento de strings.
- 06:15:00 São introduzidos o conceito de sufixos e matrizes de sufixos, com um exemplo de construção de uma matriz de sufixos para a palavra "camelo". A matriz de sufixos é uma matriz de índices classificados que permite uma representação compactada dos sufixos classificados sem armazenar os próprios sufixos, tornando-a uma alternativa eficiente em termos de espaço para uma árvore de sufixos. A matriz de prefixo comum mais longo (LCP), que armazena quantos caracteres dois sufixos classificados têm em comum, também é apresentada como uma informação importante associada à matriz de sufixos, com um exemplo de construção da matriz LCP para um determinado corda.
- 06:20:00 O vídeo discute a aplicação de matrizes de sufixos e matrizes LCP na localização e contagem de substrings únicas de maneira mais eficiente do que o algoritmo ingênuo, que requer muito espaço. Ao usar as informações armazenadas no array LCP, ele fornece não apenas uma solução rápida, mas também uma solução eficiente em termos de espaço. A matriz LCP representa o número compartilhado de caracteres entre dois sufixos adjacentes da string original. Ao examinar os valores LCP, pode-se determinar quais substrings são repetidos e eliminá-los para contar todas as substrings exclusivas de forma eficaz.
- 06:25:00 O palestrante discute o problema de encontrar a maior substring comum compartilhada entre pelo menos k de n strings dadas. Uma abordagem para resolver esse problema é a programação dinâmica, mas ela pode rapidamente se tornar difícil de manejar. Uma abordagem melhor é usar uma matriz de sufixos, que pode encontrar a solução em tempo linear. Para fazer isso, o palestrante explica que primeiro concatenamos todas as strings em uma string maior, adicionando valores de sentinela exclusivos entre cada string para evitar qualquer mistura de sufixos. Em seguida, construímos a matriz de sufixos para essa string concatenada, que nos permite encontrar a substring comum mais longa de K strings procurando por K strings com cores diferentes que compartilham o maior valor LCP.
- 06:30:00 O tutorial em vídeo discute como encontrar a maior substring comum de k cores diferentes dentro de uma string usando uma técnica de janela deslizante. A abordagem é ajustar o tamanho da janela para conter k sufixos de cores diferentes e consultar o valor LCP mínimo dentro desse intervalo. A consulta de intervalo mínimo pode ser resolvida usando uma solução linear ou uma estrutura de dados de consulta de intervalo mínimo, como uma árvore de segmentos. O tutorial também recomenda o uso de uma tabela de hash para acompanhar as cores na janela. A janela deslizante se expande para baixo para capturar as cores ausentes e diminui quando os critérios são atendidos.
- 06:35:00 Nesta seção do vídeo, o instrutor demonstra um exemplo de solução do maior problema comum de substring com uma matriz de sufixos. Os valores de janela LCP e janela LCS ajudam a rastrear o prefixo comum mais longo e os valores de substring comuns mais longos para a janela atual, enquanto o comprimento LCS e o conjunto LCS rastreiam os melhores valores até agora. O exemplo usa quatro strings e um mínimo de duas strings do pool de quatro para compartilhar a substring comum mais longa. O instrutor demonstra como expandir e encolher a janela enquanto procura a substring comum mais longa e sugere um desafio para os espectadores verificarem no site do elenco e fornece um link para uma implementação do algoritmo no GitHub.
- 06:40:00 O vídeo explica o processo de resolução do maior problema de substring comum usando a técnica de janela deslizante. Ao expandir e reduzir o tamanho da janela e usar a matriz de prefixo comum mais longa para identificar as substrings comuns, o algoritmo encontra uma solução com uma complexidade de tempo linear. O vídeo apresenta o problema da substring repetida mais longa e explica como usar a matriz de prefixo comum mais longa para encontrar com eficiência a substring repetida mais longa em uma determinada string, em comparação com a abordagem ingênua que requer tempo N ao quadrado e muita memória.
- 06:45:00 O engenheiro do Google ensina como usar uma matriz de sufixos e uma matriz LCP para encontrar a substring repetida mais longa. O valor LCP em um índice fornece o comprimento do prefixo comum mais longo entre dois sufixos adjacentes. O valor máximo na matriz LCP fornece o comprimento da substring repetida mais longa. No caso de empates, devem ser encontrados todos os valores mais longos possíveis. Em seguida, o engenheiro explica a importância das árvores de busca binárias balanceadas e como elas diferem das árvores de busca binárias tradicionais em termos de auto-ajuste para manter uma altura logarítmica em relação ao número de nós que possuem, tornando a inserção e exclusão extremamente rápidas. O conceito-chave para conseguir isso são as rotações das árvores, e elas serão discutidas mais adiante no vídeo.
- 06:50:00 O conceito de invariante de árvore e rotações de árvore em árvores de busca binária balanceadas é explicado. Uma invariante de árvore é uma regra imposta a uma árvore a ser atendida ao final de cada operação, o que é garantido pela aplicação de uma série de rotações da árvore. As rotações da árvore são transformações legítimas que se movem pelos nós em uma árvore sem quebrar a invariante da árvore de pesquisa binária se a ordem e o posicionamento dos nós forem mantidos. O processo de rotação à direita é explicado em detalhes e as etapas envolvidas na atualização de ponteiros quando os nós têm referências aos nós filho e pai são discutidas.
- 06:55:00 O tutorial em vídeo concentra-se em demonstrar como inserir nós em uma árvore AVL usando a técnica de rotação de árvore, além de explicar as propriedades que mantêm as árvores AVL balanceadas. Primeiro, o vídeo explica o que é uma árvore AVL e seu significado como o primeiro tipo de árvore de busca binária balanceada. Em seguida, o vídeo apresenta o fator de equilíbrio, que é a diferença entre a altura da subárvore direita e da subárvore esquerda. O vídeo enfatiza que o fator de equilíbrio de cada nó deve ser menos um, zero ou mais um para manter o equilíbrio da árvore AVL. O tutorial passa a discutir como lidar com casos em que isso não é verdade, o que pode ser resolvido com rotações de árvore.
Parte 8
- 07:00:00 O instrutor explica os quatro casos distintos de rotações necessárias para equilibrar uma árvore pesada à esquerda em uma árvore AVL. O instrutor também fornece pseudocódigo para inserir um nó em uma árvore AVL e explica os métodos de atualização e balanceamento. O método update calcula a altura e o fator de equilíbrio de um nó, enquanto o método balance verifica se o fator de equilíbrio de um nó viola a propriedade da árvore AVL e determina a rotação apropriada para reequilibrar a árvore. Os casos esquerda-direita e direita-esquerda também são explicados à medida que se reduzem a casos esquerda-esquerda e direita-direita após a primeira rotação.
- 07:05:00 O vídeo explica como remover elementos de uma árvore avielle, que é muito semelhante a remover elementos de uma árvore de busca binária regular. O processo de remoção pode ser dividido em duas etapas: encontrar o elemento e substituí-lo por um nó sucessor para manter invariante a árvore de busca binária. Encontrar o nó envolve comparar o elemento de destino com os nós na árvore até que uma correspondência seja encontrada ou a pesquisa chegue ao final da árvore. O processo de substituição depende se o nó a ser removido é um nó folha ou possui apenas uma subárvore esquerda ou direita, sendo o nó sucessor o filho imediato nos dois últimos casos.
- 07:10:00 O instrutor explica como remover um nó de uma árvore de pesquisa binária e fornece exemplos para os três casos de exclusão. O primeiro caso é quando o nó a remover não tem filhos, o segundo é quando tem um filho e o último é quando tem dois filhos. O instrutor também explica como aumentar o método de remoção da árvore de pesquisa binária para árvores AVL simplesmente adicionando duas linhas de código para garantir que a árvore permaneça balanceada e que o fator de balanceamento e os valores de altura permaneçam atualizados. Por fim, o instrutor fornece um link para o repositório GitHub, onde os visualizadores podem encontrar o código-fonte da árvore AVL e uma demonstração ao vivo da árvore AVL em ação.
- 07:15:00 O instrutor fornece uma explicação do código-fonte para uma implementação de árvore AVL recursiva em Java. A árvore AVL aceita um argumento de tipo genérico e armazena o valor dentro do nó, que deve ser comparável. A subclasse do nó armazena os ponteiros filho esquerdo e direito e a altura e o fator de equilíbrio do nó. A árvore pode ser exibida no terminal usando a interface da impressora de árvore, e métodos públicos como tamanho, vazio e conjunto contém são fornecidos no código. O método de inserção também é explicado usando casos básicos e valores comparativos para determinar se uma inserção foi bem-sucedida ou não.
- 07:20:00 É explicado o método de inserção privada na árvore AVL, que insere novos nós na subárvore esquerda ou direita, enquanto atualiza o fator de equilíbrio e a altura dos nós de acordo. O método update atualiza a altura e o fator de equilíbrio de um nó, e o método balance chama os métodos de rotação necessários para manter o equilíbrio da árvore. Os casos esquerda-esquerda, esquerda-direita, direita-direita e direita-esquerda são explicados, e a ordem dos métodos de atualização após a rotação é enfatizada como crucial para a árvore AVL manter seu equilíbrio.
- 07:25:00 O instrutor discute o método remove da estrutura de dados da árvore de pesquisa binária. Ele explica que, para remover um elemento, o método primeiro verifica se o elemento existe na árvore e, posteriormente, chama o método private remove. O instrutor descreve os quatro casos que podem surgir durante a remoção e propõe uma heurística para determinar de qual subárvore remover ao tentar remover um nó com ambas as subárvores. Por fim, ele lembra aos visualizadores que chamem o método update e rebalance no retorno de chamada do método remove para garantir que a árvore permaneça balanceada apesar das remoções de nós.
- 07:30:00 O engenheiro do Google apresenta a fila de prioridade indexada, uma estrutura de dados que oferece suporte a atualizações e exclusões rápidas de pares chave-valor. Ele resolve o problema de poder consultar rapidamente e alterar dinamicamente os valores em uma fila de prioridade, o que pode ser útil em várias situações, como uma sala de espera de hospital onde os pacientes precisam ser atendidos primeiro pela prioridade mais alta. O engenheiro fornece um exemplo de pacientes com diferentes prioridades e como a fila de prioridade indexada pode ajudar na atualização das prioridades em tempo real.
- 07:35:00 O vídeo discute filas de prioridade de índice que permitem a atualização dinâmica eficiente de prioridades para determinados itens. A primeira etapa ao usar uma fila de prioridade de índice é atribuir valores de índice a todas as chaves, criando um mapeamento bidirecional. Esse mapeamento deve ser bidirecional e pode ser facilitado com uma tabela hash bidirecional. A razão para usar valores de índice em chaves é permitir a indexação em arrays, que geralmente é como as filas de prioridade são implementadas.
- 07:40:00 O palestrante apresenta o conceito de fila de prioridade de índice e explica as operações que ela deve suportar, incluindo deletar chaves, obter o valor associado a uma chave, verificar se existe uma chave na fila de prioridade, obter o índice de chave com o menor valor, obtendo o menor valor no índice, podendo inserir e atualizar pares chave-valor, e as operações especializadas de atualização aumentam e diminuem a chave. A complexidade de tempo para todas essas operações é constante ou logarítmica. O palestrante também fornece uma atualização sobre a estrutura de dados da fila de prioridade tradicional, incluindo como o heap binário funciona, como inserir um novo valor na fila de prioridade e como remover itens dela.
- 07:45:00 Como implementamos uma fila de prioridade indexada com um heap binário? A primeira etapa é atribuir a cada item um valor de índice exclusivo e um valor inicial para a fila de prioridade do índice. Em seguida, usamos uma fila de prioridade indexada mínima para classificar primeiro pelo valor mais baixo e mantemos um mapa de posição para nos informar o índice de um nó na pilha para qualquer índice de chave fornecido. Além disso, mantemos uma tabela de pesquisa inversa para encontrar a chave para um determinado nó. Essas informações nos permitem acessar e manipular com eficiência a fila de prioridade para uma variedade de aplicações, como priorizar pacientes em um hospital ou clientes em um restaurante.
- 07:50:00 O vídeo discute como executar operações úteis, como inserir, atualizar e remover pares chave-valor em uma fila de prioridade de índice. O processo de inserção é semelhante a uma fila de prioridade regular, mas com a etapa adicional de atualização da posição e dos mapas inversos. O vídeo fornece pseudocódigo para o processo de inserção, mostrando como o nó é movido para cima no heap até que a invariante do heap seja satisfeita. O processo de troca envolve atualizar a posição e os mapas inversos, mas não a matriz de valores, que permanece indexada pelo índice de chave em vez do índice de nó. O vídeo também aborda brevemente a pesquisa e remoção de pares chave-valor, que envolvem etapas semelhantes à inserção, mas ao contrário.
- 07:55:00 O vídeo explica como a remoção de elementos de uma fila de prioridade indexada é aprimorada de complexidade de tempo linear para complexidade de tempo logarítmica, fazendo uso de pesquisas de posição de nó que agora são de tempo constante. O vídeo fornece um exemplo passo a passo de como remover nós, incluindo troca de nós, armazenamento de pares de valores-chave antes da remoção, limpeza de nós removidos e restauração da invariante de heap movendo o nó trocado para cima ou para baixo. Além disso, é fornecido um pseudocódigo para remover pares chave-valor, apresentando uma implementação curta de cinco linhas e um processo de limpeza de três linhas. Por fim, o vídeo descreve o método de sincronização e como ele funciona, bem como as atualizações de pares chave-valor, que são semelhantes a remover, mas também levam tempo logarítmico.
- 2019.09.19
- www.youtube.com
Curso Completo de Programação em C gratuito
Curso Completo de Programação em C gratuito
00:00:00 - 01:00:00 O vídeo "C Programming Full Course for free" ensina aos espectadores como instalar o compilador gcc, configurar um IDE e escrever código C. O vídeo aborda os fundamentos da programação C, incluindo como usar instruções printf, comentários, sequências de escape e especificadores de formato para exibir diferentes tipos de dados. O instrutor explica como criar e inicializar variáveis e como usar operadores aritméticos e de incremento/decremento. Além disso, o vídeo aborda a aceitação da entrada do usuário usando scanf e a formatação da saída usando printf. O instrutor também discute funções matemáticas úteis em C e como usá-las para calcular a circunferência e a área de um círculo com base na entrada do usuário para o raio. O vídeo enfatiza que, embora C seja uma linguagem difícil, qualquer pessoa pode aprendê-la com persistência e esforço.
01:00:00 - 02:00:00 O vídeo do YouTube "Programação C Full Course for free" ensina conceitos de programação em linguagem C. Nesta seção de vídeo, o instrutor aborda tópicos como instruções if/else, instruções switch, operadores lógicos, funções e loops. O instrutor explica as instruções condicionais, permitindo que o programa faça escolhas com base nas condições e como a instrução switch é uma versão mais eficiente da instrução else if. Além disso, o instrutor se aprofunda para mostrar como converter unidades de temperatura, criar um programa de calculadora simples, usar operadores lógicos para melhorar a eficiência do programa e como usar funções para minimizar a redundância de código. Por fim, o instrutor explica o operador ternário e como as funções de string podem auxiliar na criação do programa.
02:00:00 - 03:00:00 Este Curso Completo de Programação em C abrange uma ampla variedade de tópicos, começando com a explicação da diferença entre loop while e do-while e como usar loops aninhados para criar formas. Em seguida, o vídeo aborda os conceitos básicos de arrays e como percorrer e exibir elementos em um array unidimensional, antes de passar para arrays bidimensionais e como criar uma grade 2D ou tabela de dados. Em seguida, o instrutor apresenta o conceito de troca de variáveis, algoritmos de classificação, como classificação por bolhas, e ensina sobre structs e typedef em C, além de gerar números aleatórios e fazer um jogo de adivinhação de números. No geral, este curso fornece uma compreensão abrangente e aprofundada dos conceitos de programação C.
03:00:00 - 04:00:00 Este vídeo do YouTube intitulado "C Programming Full Course for free" abrange uma ampla variedade de tópicos de programação C, incluindo a criação de jogos como adivinhação de números e jogos de perguntas e respostas, além de conceitos como memória, ponteiros, operadores bit a bit e E/S de arquivo. Além disso, o vídeo explica como criar um jogo Tic Tac Toe que usa loops for aninhados e instruções if para verificar um vencedor e gerar movimentos aleatórios para o jogador do computador. O instrutor fornece explicações e demonstrações claras ao longo do vídeo, tornando-o um recurso valioso para qualquer pessoa interessada em aprender a programar em C.
04:00:00 - 04:00:00 O instrutor continua construindo o jogo Tic-Tac-Toe em C, adicionando uma verificação para garantir que o local escolhido esteja vazio antes de fazer um movimento e criar uma função para imprimir o vencedor. Eles então adicionam uma opção "reproduzir novamente" usando um loop do while e redefinem as variáveis no início de cada loop. O código será compartilhado na seção de comentários para uso dos usuários.
Parte 1
- 00:00:00 O autor explica a importância de aprender C, que é uma linguagem de nível médio que atua como uma ponte entre o software de alto nível e o hardware de baixo nível. C surgiu na década de 1970 e é amplamente utilizado para vários fins, incluindo a escrita de compiladores, sistemas operacionais e bancos de dados. O YouTuber também fornece instruções sobre como configurar um IDE e instalar as extensões e o compilador necessários para começar a escrever o código C. No entanto, o YouTuber adverte que C é uma linguagem difícil para iniciantes, mas com persistência e esforço qualquer pessoa pode aprendê-la.
- 00:05:00 O vídeo explica como instalar o gcc em um sistema Mac ou Linux e como adicionar o caminho para o compilador gcc abaixo das variáveis de ambiente. Após a instalação do gcc, o vídeo explica como configurar a tarefa de compilação padrão para que o VS Code saiba como compilar o programa. O vídeo recomenda aumentar o tamanho da fonte e ativar o salvamento automático para evitar dores de cabeça no futuro. O vídeo também aborda os fundamentos da programação C e inclui funções importantes, como inclusão de hashtag, std para entrada/saída io padrão e impressão de parênteses. Por fim, o vídeo enfatiza a necessidade de adicionar a instrução return 0 ao final da função principal para verificar se há algum erro.
- 00:10:00 Nesta seção do tutorial de programação C, o instrutor mostra como usar instruções printf para imprimir texto e como adicionar um novo caractere de linha usando uma sequência de escape. Ele também demonstra como compilar e executar um arquivo C usando o prompt de comando e explica a finalidade dos comentários na programação C. O vídeo aborda os fundamentos da programação em C e fornece dicas úteis para iniciantes.
- 00:15:00 Nesta seção do tutorial em vídeo sobre programação C, o instrutor explica como usar comentários e sequências de escape em seu código. Os comentários são usados para explicação, descrição ou notas para qualquer pessoa que esteja lendo o código. Os comentários de uma linha são feitos com duas barras, enquanto os comentários de várias linhas são feitos com uma barra seguida de um asterisco e terminando com um asterisco seguido de uma barra. As sequências de escape, por outro lado, são combinações de caracteres que especificam ações dentro de uma linha de texto ou string. As sequências de escape mais comumente usadas são para criar novas linhas e tabulações dentro de strings de texto. O instrutor também demonstra como exibir aspas, aspas simples e barras invertidas usando sequências de escape.
- 00:20:00 o vídeo discute como criar variáveis em programação C. Primeiro, você deve declarar uma variável e atribuir um nome e tipo de dados a essa variável. Em seguida, você deve inicializar esta variável definindo-a igual a algum valor. O vídeo fornece exemplos de diferentes tipos de dados, incluindo números inteiros, pontos flutuantes, caracteres e matrizes. O vídeo também explica como exibir o valor armazenado em uma variável usando uma instrução printf e um especificador de formato.
- 00:25:00 Nesta seção do vídeo, o instrutor explica como usar especificadores de formato para exibir diferentes tipos de dados na programação C. Por exemplo, para exibir uma matriz de caracteres, use o sinal de porcentagem seguido de 's' para string. Para exibir uma variável de caractere, use percent c, e para exibir um número de ponto flutuante, use percent f. O instrutor também discute tipos de dados como chars, floats, integers e doubles, com doubles tendo 64 bits de precisão e retendo mais dígitos significativos do que floats. Booleanos também são introduzidos, armazenando verdadeiro ou falso e usando um byte de memória. Diferentes especificadores de formato e maneiras de personalizá-los serão discutidos no próximo vídeo.
- 00:30:00 Aprendemos que booleanos podem ser exibidos usando percent d com um referindo-se a verdadeiro e zero a falso. Os caracteres podem armazenar inteiros dentro do intervalo de 128 negativo a 127 positivo, com suas representações sendo mostradas usando especificadores de formato de porcentagem d ou porcentagem c. Variáveis não assinadas dobram nosso intervalo de números positivos para caracteres e shorts, então char pode armazenar números entre 0 e 255, enquanto shorts pode armazenar dígitos de 32.768 negativo a 32.767 positivo se assinado e 0 a 65.535 se não assinado. Aprendemos que você pode usar short em vez de short int como abreviação. Inteiros podem armazenar números inteiros que podem ser valores positivos ou negativos.
- 00:35:00 É importante observar que existem diferentes especificadores de formato para diferentes tipos de dados e usar o errado pode resultar em erros ou resultados inesperados. Embora existam muitos tipos de dados disponíveis na programação C, focaremos principalmente em caracteres, matrizes de caracteres, duplos, booleanos e inteiros neste curso.
- 00:40:00 O instrutor explica os especificadores de formato, que definem e formatam os tipos de dados a serem exibidos de uma maneira especificada. Para definir uma largura mínima de campo para exibir a saída, um número é adicionado após o sinal de porcentagem para alocar espaços específicos. Usar um sinal negativo após o sinal de porcentagem à esquerda alinha os dados. O vídeo também aborda as constantes, que são valores fixos que não podem ser alterados pelo programa durante sua execução. Para converter uma variável em uma constante, o tipo de dados é precedido pela palavra-chave 'const' e a convenção de letras maiúsculas é seguida para nomear a constante. Operadores aritméticos como adição, subtração, multiplicação e divisão também são abordados, onde a divisão com números inteiros pode truncar porções decimais, exigindo o uso de float ou double para armazenar o resultado, e o operador de módulo é usado para obter o resto de qualquer divisão.
- 00:45:00 O instrutor explica os operadores aritméticos na programação C, incluindo o módulo, que pode ser usado para determinar rapidamente se um número é par ou ímpar, encontrando o resto quando dividido por 2. O vídeo também aborda os operadores de incremento e decremento, que podem ser usados para aumentar ou diminuir uma variável em 1, e operadores de atribuição aumentados, que permitem aos usuários realizar uma operação aritmética em uma variável e atribuir o resultado de volta à mesma variável usando um atalho. Por fim, o instrutor fornece uma visão geral sobre como aceitar a entrada do usuário com a função scanf e prompts na programação C.
- 00:50:00 O instrutor explica como aceitar as entradas do usuário na programação C usando a função scanf com o especificador de formato apropriado para o tipo de variável que está sendo usado. A seção aborda a aceitação de números inteiros e strings, com a ressalva de que aceitar strings com espaços requer a função fgets em vez de scanf por causa dos espaços em branco. O instrutor também explica como formatar a string depois de usar fgets para se livrar de novos caracteres de linha. A seção termina com uma visão geral da formatação da instrução printf para melhorar a legibilidade.
- 00:55:00 Nesta seção do vídeo, o instrutor discute funções matemáticas úteis em C ao incluir o arquivo de cabeçalho de matemática. Raiz quadrada, potência, arredondamento (usando teto e piso), valor absoluto, logaritmos e funções trigonométricas são explicados com exemplos de como usá-los no código. Posteriormente, o instrutor demonstra como escrever um programa que calcula a circunferência de um círculo com base na entrada do usuário para o raio e vai além para calcular e exibir a área do círculo usando pi vezes a fórmula do raio ao quadrado.
Parte 2
- 01:00:00 Nesta seção do vídeo, o instrutor demonstra como calcular a circunferência e a área de um círculo usando a linguagem de programação C e como encontrar a hipotenusa de um triângulo retângulo, o que requer o uso da função raiz quadrada do arquivo de cabeçalho math.h. O instrutor também apresenta instruções if e como elas são usadas para adicionar opções a um programa, verificando as condições e executando o código de acordo. Ele demonstra como usar a condição maior ou igual a e o operador de comparação de sinais de igual duplo, bem como usar instruções else para fornecer uma saída diferente quando uma condição for falsa.
- 01:05:00 o vídeo discute as instruções if e else if na programação C. Essas instruções permitem que o programa verifique se uma condição é verdadeira e execute um subconjunto específico de código se for, e se não for, o programa moverá para o próximo bloco para verificar outra condição. Se todas as condições forem falsas, o programa executará o código que está dentro do bloco else. Além disso, o vídeo apresenta o uso de uma instrução switch como uma alternativa mais eficiente ao uso de várias outras instruções if. A instrução switch permite que um valor seja testado quanto à igualdade em muitos casos usando a palavra-chave case. Por fim, o vídeo enfatiza a importância de adicionar uma instrução break após cada caso em uma instrução switch para sair do switch assim que um caso correspondente for encontrado.
- 01:10:00 Nesta seção do vídeo, o instrutor ensina como criar um programa que converte temperatura de Celsius para Fahrenheit ou vice-versa. O programa aceita a entrada do usuário para a unidade de medida (Celsius ou Fahrenheit) e a temperatura atual e, em seguida, usa instruções if/else e as fórmulas apropriadas para realizar a conversão. O instrutor também demonstra como usar a função to_upper para lidar com distinção entre maiúsculas e minúsculas e como usar scanf para aceitar números de ponto flutuante. O programa solicita ao usuário uma entrada e exibe a temperatura convertida.
- 01:15:00 Nesta seção do curso, o instrutor demonstra como criar um programa em C que converte unidades de temperatura (Celsius para Fahrenheit e vice-versa) com base na entrada do usuário. O programa solicita que o usuário insira a temperatura e a unidade de medida, aceita a entrada usando scanf e, em seguida, usa uma série de declarações condicionais para converter as unidades de temperatura conforme necessário. O instrutor explica o uso de especificadores de formato, a fórmula de conversão de Celsius para Fahrenheit e a instrução switch para lidar com diferentes tipos de operações no fluxo do programa. O programa final é postado na seção de comentários para download e revisão.
- 01:20:00 Nesta seção do vídeo, o instrutor demonstra como criar um programa de calculadora simples em C que pode realizar adição, subtração, multiplicação e divisão. O programa usa uma instrução switch para determinar qual operação executar com base na entrada do usuário. Adicionalmente, é explicada a utilização de operadores lógicos, especificamente o operador "e", que verifica se um conjunto de condições é verdadeiro. O instrutor fornece exemplos de como usar operadores lógicos para verificar se uma temperatura cai dentro de um determinado intervalo e como incluir variáveis booleanas nas verificações de condição.
- 01:25:00 Discute-se o operador lógico or e o operador não lógico. O operador lógico ou verifica se pelo menos uma condição é verdadeira, enquanto o operador não lógico inverte o estado de uma condição. O operador or pode ser usado para verificar várias condições adicionando mais barras verticais. Por outro lado, o operador not pode oferecer mais opções para a forma como um programa é escrito. Esses operadores lógicos podem ajudar a criar condições mais complexas e melhorar a eficiência de um programa.
- 01:30:00 O instrutor ensina como usar funções na programação C para evitar a repetição do mesmo código. Ao criar uma nova função, o código pode ser escrito uma vez e reutilizado várias vezes simplesmente chamando a função. O instrutor passa a discutir argumentos e parâmetros, com um exemplo de transmissão de matrizes de caracteres e números inteiros como argumentos para uma função. Os parâmetros precisam ser declarados na declaração da função para tornar a função ciente das variáveis que estão sendo passadas para ela. Sem um conjunto correspondente de parâmetros, a função não pode ser chamada.
- 01:35:00 Nesta seção da transcrição, o palestrante explica o conceito da instrução return e como ela pode retornar um valor para a função de chamada. Eles demonstram um exemplo de uma função chamada "square" que aceitará um argumento, elevará esse argumento ao quadrado e retornará o resultado para a função de chamada. Eles também discutem a sintaxe do operador trinário, um atalho para usar uma instrução if-else ao atribuir ou retornar um valor, e mostram um exemplo de como ele pode ser usado para encontrar o máximo de dois inteiros. O palestrante também enfatiza a importância de combinar o tipo de dados ao usar a palavra-chave return na declaração da função.
- 01:40:00 Aprendemos sobre o operador ternário, que serve como um atalho para usar uma instrução if-else ao atribuir ou retornar um valor. O operador consiste em uma condição, seguida de um ponto de interrogação, um valor a ser retornado se a condição for verdadeira, dois pontos e o valor a ser retornado se a condição for falsa. Também discutimos protótipos de funções, que garantem que as chamadas para uma função sejam feitas com o número e o tipo corretos de argumentos. Ao adicionar um protótipo de função antes da função principal, podemos evitar comportamento inesperado e receber erros se forem usados argumentos incorretos.
- 01:45:00 Nesta seção do vídeo, o instrutor explica os protótipos de função em C e suas vantagens, além de apresentar algumas funções de string úteis que já estão escritas em C, como comprimento de string, comparação de string, string lower, string superior e gato de corda. O instrutor dá exemplos de como cada uma dessas funções funciona e demonstra seus resultados. A função de comparação de strings retorna zero se as duas strings comparadas forem iguais e outros números se não forem. O instrutor termina a seção incluindo um trecho de código que usa essas funções de string.
- 01:50:00 O instrutor aborda for loops, que repetem uma seção de código um número limitado de vezes. Ele fornece um exemplo de contagem de 1 a 10 usando um loop for e explica as três instruções necessárias para um loop for: declarar um índice, definir uma condição por quanto tempo repetir o código e uma maneira de aumentar ou diminuir o índice. Ele também demonstra diferentes formas de incrementar e decrementar o índice. O instrutor então passa a explicar loops while, que repetem uma seção de código possivelmente ilimitadas vezes, desde que uma determinada condição permaneça verdadeira, e dá um exemplo de solicitação de nome aos usuários até que o usuário insira uma resposta válida.
- 01:55:00 Nesta seção do vídeo, o instrutor demonstra como usar fgets em vez de scanf para entrada do usuário na programação C. Eles então usam um loop while para solicitar ao usuário que digite seu nome e gritam com eles se não digitarem seu nome corretamente. O instrutor então passa a discutir o loop do-while e fornece uma demonstração de um programa que solicita ao usuário que insira quantos números desejar, desde que sejam maiores que zero, e calcula a soma desses números.
Parte 3
- 02:00:00 Nesta seção do Curso Completo de Programação em C, o instrutor explica a diferença entre um loop while e um loop do-while em C. Enquanto um loop while verifica a condição primeiro e depois executa o código se a condição for verdadeiro, um loop do-while executa o código uma vez e, em seguida, verifica a condição para ver se é verdadeira antes de continuar. O instrutor demonstra isso com um código de exemplo e explica como modificar um loop while para um loop do-while. A seção também aborda loops aninhados, que é um loop dentro de outro loop, e demonstra um exemplo de uso de loops aninhados para imprimir um retângulo de símbolos com base nos valores de entrada do usuário para linhas, colunas e símbolos.
- 02:05:00 Nesta seção do vídeo, o instrutor demonstra como criar formas retangulares usando loops aninhados em C. Ele permite que o usuário insira um símbolo e o número de linhas e colunas para o retângulo, mas também mostra como para limpar o buffer de entrada para permitir a entrada adequada do usuário. O instrutor também explica a diferença entre as instruções continue e break no contexto dos loops C, em que continue pulará o restante de uma seção de código e forçará a próxima iteração de um loop, enquanto break sairá totalmente de um loop. Finalmente, o instrutor define o conceito de arrays como uma estrutura de dados que pode armazenar muitos valores do mesmo tipo de dados e mostra como transformar uma variável em um array.
- 02:10:00 O vídeo aborda o conceito de arrays na linguagem de programação C. Arrays são uma maneira de armazenar vários valores do mesmo tipo de dados em uma estrutura de dados de tamanho fixo. O vídeo demonstra como inicializar um array e acessar elementos específicos usando números de índice. Existem várias maneiras de inicializar uma matriz, como atribuir valores imediatamente ou atribuir valores posteriormente no programa. O vídeo também explica como percorrer e imprimir todos os elementos de uma matriz usando um loop for.
- 02:15:00 O vídeo aborda como percorrer e exibir os elementos de uma matriz na programação C. O instrutor demonstra o uso de um loop for e uma instrução printf, com o índice do loop for sendo usado para acessar os elementos da matriz. Eles também mostram como calcular o número de vezes que o loop deve iterar usando o tamanho do operador, que será atualizado automaticamente se elementos forem adicionados ou removidos da matriz. O instrutor então passa a criar uma matriz bidimensional, que é uma matriz em que cada elemento é uma matriz. Eles demonstram como inicializar e organizar um array bidimensional, usando o exemplo de uma simples grade ou tabela de dados.
- 02:20:00 O instrutor explica como declarar e atribuir valores a uma matriz bidimensional na programação C. Eles também explicam como exibir os elementos de uma matriz bidimensional usando loops aninhados e o especificador de formato "d". O instrutor então mostra como calcular o número de linhas e colunas de uma matriz bidimensional usando o tamanho do operador e o tamanho de uma das linhas e usando o tamanho de um dos elementos encontrados na primeira linha. A seção termina com um exemplo de como testar o código com uma nova linha adicionada ao array 2D.
- 02:25:00 Nesta seção do vídeo, o instrutor explica como criar um array bidimensional em C, que é um array de arrays onde cada elemento é um array inteiro. Dois índices são usados para acessar um dos elementos - um para a linha e outro para a coluna. O instrutor também mostra como criar uma matriz de strings, que é uma matriz 2D de caracteres individuais, exceto que cada elemento é uma string. Para exibir uma matriz de strings, um loop for pode ser usado. Finalmente, o instrutor explica como as variáveis podem ser trocadas em C introduzindo uma terceira variável como armazenamento temporário para o valor. A troca de variáveis é importante nos algoritmos de ordenação, que serão abordados no próximo tópico.
- 02:30:00 O instrutor ensina como trocar os valores de duas variáveis em C, tanto para inteiros quanto para arrays de caracteres. Usando variáveis temporárias e a função de cópia de string, o instrutor mostra como trocar valores e evitar comportamentos inesperados com matrizes de caracteres se o comprimento do segundo argumento for menor que o primeiro. O instrutor também sugere imaginar variáveis como copos contendo fluido para entender melhor os valores de troca e fornece código de exemplo na seção de comentários. Em seguida, o instrutor explica como escrever um programa para classificar elementos dentro de uma matriz, primeiro com uma matriz de números inteiros e depois com uma matriz de caracteres. O instrutor declara uma função separada para classificação e usa loops for aninhados para percorrer a matriz e comparar valores para classificação.
- 02:35:00 O palestrante discute como classificar elementos de uma matriz em C usando o algoritmo de classificação por bolhas. Eles explicam o uso de variáveis temporárias e instruções if, e como o tamanho do número que está sendo classificado afeta sua posição final na matriz. O palestrante também demonstra como classificar uma matriz de caracteres alterando o tipo de dados e a função de impressão. Em seguida, eles introduzem o conceito de structs como uma forma de organizar membros relacionados em um bloco de memória, com a capacidade de imitar objetos do mundo real. Uma struct é definida usando a palavra-chave struct seguida por um nome de tag e um conjunto de chaves para representar seus membros.
- 02:40:00 Nesta seção do vídeo, o instrutor ensina sobre structs e typedef na linguagem de programação C. As structs permitem que um programador agrupe valores relacionados sob um nome em um bloco de memória e podem ser usados para atribuir valores a membros com diferentes tipos de dados. A palavra-chave typedef fornece um apelido a um tipo de dados existente, o que torna mais fácil usar o tipo de dados no código. O instrutor também mostra um exemplo de como criar uma estrutura com três membros e atribuir valores a eles. O vídeo fornece um código de amostra para usuários que gostariam de usá-lo.
- 02:45:00 A struct é criada fora da função principal e recebe um nome de tag, "student", e contém uma matriz de caracteres para o nome e uma variável flutuante para o GPA. Uma matriz de quatro alunos é inicializada e, em seguida, colocada em uma matriz chamada "alunos". Usando um loop for, o programa percorre a matriz e imprime o nome de cada aluno e o GPA usando o operador de acesso de membro ponto. Por fim, o vídeo explica que, se usarmos a palavra-chave "typedef" com um struct, não precisamos mais usar a palavra-chave struct para criar o struct e podemos usar o apelido que atribuímos a ele.
- 02:50:00 O instrutor ensina como criar arrays de structs em C, onde cada elemento do array é um struct contendo os dados de cada aluno como nome e GPA. O instrutor também aborda o uso de enums, que são tipos definidos pelo usuário de identificadores inteiros nomeados que podem tornar um programa mais legível, substituindo valores inteiros por nomes associados, tornando o código mais fácil de entender para o programador e para qualquer pessoa que revise o código. A estrutura de enums é descrita e o instrutor demonstra como usar enums em instruções if-else para imprimir resultados diferentes com base no valor de uma variável enum.
- 02:55:00 Nesta seção do vídeo, o instrutor demonstra como gerar números aleatórios na programação C. O tempo atual é usado para gerar uma semente para a função rand, que gera um número aleatório entre 0 e 32767. Para obter um número aleatório dentro de um determinado intervalo, o operador módulo pode ser usado. O instrutor fornece um exemplo de geração de um número aleatório entre 1 e 6 (para jogar um dado) e para jogar três dados. Um jogo de adivinhação de números também é introduzido usando o conhecimento de geração de números aleatórios. As constantes para o intervalo mínimo e máximo são definidas e o usuário é solicitado a adivinhar o número. O programa usa a função rand para gerar um número aleatório dentro do intervalo fornecido, e o usuário recebe feedback para ajustar seu palpite até que o número correto seja inserido.
Parte 4
- 03:00:00 O instrutor ensina a criar um jogo de adivinhação de números em C, onde o programa gera um número aleatório entre dois valores especificados, solicita que o usuário adivinhe o número e fornece feedback se o palpite for muito alto, muito baixo , ou correto. O programa usa um loop do-while para garantir que pelo menos um palpite seja feito e conta o número de palpites feitos pelo usuário. O instrutor também adiciona algumas decorações de texto para tornar a saída mais atraente visualmente. Este exemplo demonstra o uso de condicionais, loops, entrada do usuário e geração de números aleatórios em C.
- 03:05:00 O instrutor mostra como criar um jogo de perguntas e respostas em C. O jogo usa uma matriz de caracteres bidimensional para armazenar as perguntas e uma matriz de caracteres bidimensional separada para armazenar as opções. As respostas corretas são armazenadas em uma matriz de caracteres unidimensional. O jogo calcula o número de perguntas que possui e usa um loop for para percorrê-las uma a uma, exibindo-as junto com suas opções possíveis. Para fazer isso, o instrutor usa um loop for aninhado que começa com cada quarta string dentro da matriz de opções. Este for ciclos quatro vezes, exibindo as quatro opções possíveis para cada pergunta.
- 03:10:00 O instrutor mostra como criar um jogo de perguntas e respostas simples em C que faz perguntas ao usuário e verifica suas respostas. O código usa um loop for aninhado para exibir as perguntas e opções, aceita a entrada do usuário usando scanf e converte caracteres minúsculos em maiúsculos usando a função "toupper". O programa então verifica se o palpite do usuário corresponde à resposta correta e incrementa a pontuação de acordo. Depois que todas as perguntas forem respondidas, o programa exibe a pontuação final. O instrutor também explica brevemente os operadores bit a bit e demonstra como usar cinco diferentes operadores bit a bit em C.
- 03:15:00 Aprendemos sobre operações bit a bit na programação C. Começamos com o operador AND, que, quando aplicado a dois números binários, atribui um ao nosso resultado somente se ambos os bits correspondentes forem um. Em seguida, passamos para o operador OR, que atribui um ao nosso resultado se algum dos bits correspondentes for um. O operador OU exclusivo atribui um ao resultado se apenas um bit correspondente for um. Também aprendemos sobre os operadores de deslocamento à esquerda e à direita que deslocam bits em um número binário para a esquerda ou para a direita. Deslocar os bits para a esquerda efetivamente dobra o número, enquanto deslocá-lo para a direita tem o efeito oposto.
- 03:20:00 O vídeo explica a memória na programação C, que é uma matriz de bytes dentro da RAM, sendo cada unidade um bloco de memória que pode conter um valor. Um endereço de memória aponta para onde um bloco de memória está localizado na RAM e é como um endereço de rua. Ao declarar uma variável, ela separa alguns blocos de memória para manter um valor associado a um endereço de memória. Cada variável usa um bloco de memória de um byte, e o vídeo mostra os endereços de memória e tamanhos de vários caracteres como exemplos. O vídeo também explica brevemente os valores hexadecimais, que usam números de 0 a 9 e letras de a a f para criar 16 valores possíveis para cada dígito. Por fim, o vídeo aborda tipos de dados curtos, que usam dois bytes de memória.
- 03:25:00 O instrutor explica os fundamentos da memória na programação C, incluindo como as variáveis usam blocos de memória e como as matrizes usam vários blocos de memória com base em seu tamanho e tipo de dados. Ele também apresenta o conceito de ponteiros, que armazenam um endereço de memória como um valor para outra variável, e explica como eles podem ser usados para executar determinadas tarefas com mais facilidade. O instrutor demonstra como exibir o valor e o endereço de uma variável e como criar um ponteiro do mesmo tipo de dados da variável para a qual está apontando.
- 03:30:00 Aprendemos sobre ponteiros em programação C. Os ponteiros são declarados usando um asterisco como o operador de indireção e uma convenção de nomenclatura comum é usar um "p" minúsculo seguido pelo nome da variável com a primeira letra maiúscula. O valor de um ponteiro é um endereço e podemos acessar o valor armazenado nesse endereço usando o operador de indireção. É importante certificar-se de que os tipos de dados do ponteiro e a variável para a qual ele está apontando sejam consistentes. Ponteiros também podem ser passados como argumentos para funções, permitindo que a função acesse e modifique o valor armazenado na variável apontada. Além disso, os ponteiros podem ser declarados e inicializados em duas etapas, mas atribuir um valor imediatamente é uma boa prática.
- 03:35:00 O instrutor explica ponteiros em programação C. Um ponteiro é uma variável que contém um endereço de memória para outra variável, array e muito mais. Para declarar um ponteiro, você usa o operador de indireção. Para atribuir um valor a um ponteiro, você usa o mesmo operador. O instrutor mostra como gravar em um arquivo em C usando ponteiros, fopen, fwrite e fclose. Para escrever em um arquivo, você precisa criar um ponteiro para um arquivo e usar `fprintf` para escrever no arquivo. O instrutor também demonstra E/S de arquivo excluindo um arquivo e gravando em um arquivo em um local específico no diretório de um computador.
- 03:40:00 O instrutor mostra como ler o conteúdo de um arquivo em programação C, criando um ponteiro com o tipo de dados "arquivo" e usando a função fopen para abrir o arquivo. O instrutor demonstra como usar um buffer para conter uma matriz de caracteres para manter uma linha do documento de texto por vez e como ler uma única linha do arquivo usando a função fgets. A seção também inclui como exibir todas as linhas de um arquivo usando um loop while e como adicionar detecção de arquivo para verificar se o arquivo existe antes de tentar lê-lo.
- 03:45:00 Nesta seção do vídeo, o instrutor repassa os protótipos de função que serão utilizados no programa, incluindo funções para reiniciar o tabuleiro, imprimir o tabuleiro, verificar espaços livres, movimento do jogador, movimento do computador, cheque vencedor , e vencedor de impressão. Depois de declarar essas funções, o instrutor discute algumas variáveis globais a serem usadas, incluindo uma matriz 2D de personagens denominada tabuleiro, bem como constantes para os personagens do jogador e do computador. A função principal é discutida a seguir, onde ela declara uma variável local para o vencedor, define-a como um espaço vazio, redefine o tabuleiro e a imprime. O vídeo também inclui detalhes sobre loops for aninhados usados na função da placa de reinicialização e uma instrução printf usada na placa de impressão.
- 03:50:00 Nesta seção do Curso Completo de Programação em C, o instrutor explica como criar um loop while na função principal que envolverá a função da placa de impressão. A condição do loop while é que, se o vencedor for um espaço vazio e o valor retornado da chamada da função de verificação de espaços livres não for igual a zero, o loop continuará. A função de verificação de espaços livres também é criada usando dois loops for aninhados para percorrer o array 2D de caracteres e decrementar a variável local de espaços livres se algum ponto estiver ocupado. A função de movimento do jogador é explicada, solicitando ao usuário que insira os números das linhas e colunas para fazer um movimento e verifica se o local está ocupado ou não. A função de verificação do vencedor também é criada para verificar cada linha em busca de uma condição de ganho e para verificar cada coluna em busca de uma condição de ganho.
- 03:55:00 O instrutor repassa o código para verificar as linhas, colunas e diagonais para um vencedor em um jogo Tic Tac Toe. Eles explicam o uso de loops for e instruções if para percorrer os elementos no tabuleiro do jogo e verificar se há correspondências. Se houver um vencedor, a função retornará o valor do caractere do elemento vencedor. Caso contrário, um caractere vazio é retornado. O instrutor então fornece o código para o movimento do computador, que envolve a geração de coordenadas aleatórias para colocar seu símbolo no tabuleiro. Antes de gerar números aleatórios, o programa verifica se há espaços disponíveis no tabuleiro.
- 04:00:00 O instrutor continua construindo o jogo Tic Tac Toe em C. Eles adicionam uma verificação para garantir que o local gerado seja um espaço vazio antes de fazer um movimento. Se não houver mais espaços disponíveis, a função "vencedor de impressão" é invocada com um espaço vazio, significando que o jogo está empatado. Eles explicam que esta função é bastante fácil, pois imprime "Você ganha" se o vencedor for o jogador, "Você perde" se o vencedor for o computador e "É um empate" se não houver vencedor. O instrutor implementa uma opção "reproduzir novamente" usando um loop do while e redefine as variáveis vencedoras e de resposta no início de cada loop. O jogo é executado e testado várias vezes, com o instrutor explicando cada etapa. Por fim, eles mencionam que o código será postado na seção de comentários para uso dos usuários.
- 2021.10.07
- www.youtube.com
Conceitos Fundamentais de Programação Orientada a Objetos
Conceitos Fundamentais de Programação Orientada a Objetos
Os quatro conceitos fundamentais da programação orientada a objetos são abstração, encapsulamento, herança e polimorfismo. Antes de mergulhar em seus significados, é importante entender o que é um objeto. Um objeto representa algo do mundo real, que pode ser físico, como um carro ou um livro, ou não físico, como uma consulta odontológica ou uma conta bancária.
No contexto da programação orientada a objetos, um objeto refere-se a qualquer coisa de interesse para o aplicativo de software que está sendo desenvolvido, onde os dados precisam ser armazenados e processados. Objetos também são conhecidos como entidades.
A abstração é o primeiro conceito fundamental, que envolve a simplificação da realidade, concentrando-se apenas nos dados e tarefas relevantes relacionados a um objeto. Ao projetar um aplicativo para processar dados sobre uma pessoa, por exemplo, apenas os dados e operações necessários são considerados.
Para criar objetos programaticamente, uma classe é necessária. Uma classe serve como modelo para a criação de objetos e é escrita por um programador para definir os atributos (também conhecidos como campos ou propriedades) e as operações (também conhecidas como comportamentos ou métodos) de um objeto. Os atributos descrevem os dados do objeto, enquanto as operações representam as ações que podem ser executadas pelo objeto.
O encapsulamento é o segundo conceito fundamental e envolve ocultar a complexidade do funcionamento interno de um objeto de outros programas e programadores. Muitas vezes, é referido como ocultação de informações porque os dados e as funções dentro de um objeto são vinculados e protegidos contra interferência externa. Programadores experientes geralmente criam classes que são usadas por programadores juniores, e bibliotecas de classes compiladas protegem a propriedade intelectual.
Herança é o terceiro conceito fundamental, permitindo a uma classe derivar seus métodos e propriedades de outra classe. Isso leva a uma hierarquia de classes, onde as subclasses herdam de uma superclasse. Por exemplo, uma classe de funcionário herda de uma classe de pessoa e uma classe de cliente também herda da classe de pessoa. Isso cria um tipo de relacionamento, com subclasses estendendo as propriedades e métodos de sua superclasse.
O polimorfismo, o último conceito fundamental, permite que uma classe implemente métodos herdados à sua própria maneira. Diferentes subclasses da mesma superclasse podem ter diferentes implementações para os métodos herdados. O polimorfismo permite que diferentes formas de objetos com a mesma interface se comportem de maneira diferente, dependendo de sua implementação de subclasse específica.
Para resumir, a abstração simplifica a realidade, o encapsulamento esconde a complexidade, a herança estabelece hierarquias de classes e o polimorfismo permite diversas implementações de métodos herdados. Esses conceitos fundamentais formam a base da programação orientada a objetos.
- 2020.11.01
- www.youtube.com
Curso de Programação Orientada a Objetos (OOP) em C++
Curso de Programação Orientada a Objetos (OOP) em C++
Este vídeo fornece uma visão geral da programação orientada a objetos (OOP) em C++. Ele explica os conceitos fundamentais de POO, como classes, objetos e métodos. O instrutor demonstra a criação de uma classe C++ e seus membros, enfatizando a importância de declarar variáveis como tipos de dados definidos pelo usuário. Modificadores de acesso como private, public e protected são explicados em relação ao acesso aos membros do objeto.
O vídeo também aborda a implementação dos princípios OOP, incluindo encapsulamento, abstração, herança e polimorfismo. Ele mostra exemplos de como esses princípios são aplicados no código, como a criação de construtores e classes abstratas. O instrutor destaca os benefícios da OOP, como simplificar o desenvolvimento de software e ocultar a complexidade dos usuários.
Além disso, o vídeo explora o conceito de herança, em que uma classe derivada herda propriedades de uma classe base. O instrutor demonstra o processo de criação de classes derivadas e explica como elas podem ter suas próprias propriedades exclusivas além das herdadas.
O vídeo termina com discussões sobre funções virtuais e polimorfismo. Ele explica como o polimorfismo permite que objetos e métodos tenham várias formas, permitindo que uma referência de classe pai seja usada com objetos de classe filho. O conceito de funções virtuais é introduzido, enfatizando que a versão mais derivada de uma função é executada quando invocada.
No geral, este vídeo visa fornecer uma compreensão abrangente de OOP em C++, abrangendo conceitos essenciais, princípios e implementações práticas. A instrutora incentiva os espectadores a seguirem seu canal, Code Beauty, e agradece comentários sobre os vídeos.
- 00:00:00 Este vídeo explica os fundamentos da programação orientada a objetos e como ela funciona na prática. As classes são um conceito-chave na programação orientada a objetos e as variáveis devem ser declaradas como tipos de dados definidos pelo usuário para serem usadas.
- 00:05:00 Neste vídeo, uma classe C++ é criada e membros são adicionados. A classe tem três atributos, nome, empresa e idade. Uma instância da classe é criada e o número da variável é atribuído a ela.
- 00:10:00 Neste vídeo, o instrutor explica como acessar os membros de um objeto em C++. Os modificadores de acesso, como privado, público e protegido, determinam como os membros de um objeto são acessíveis. Um método de classe pode ser usado para descrever o comportamento de um objeto.
- 00:15:00 Este vídeo explica como a programação orientada a objetos (OOP) funciona em C++. Uma função é criada com o tipo de retorno void e a função é chamada usando a mesma sintaxe da função que foi introduzida. A função é invocada cinco vezes, cada vez com um nome de funcionário e uma empresa diferentes. Os nomes dos funcionários e os valores da empresa são copiados para um novo objeto funcionário e os atributos do objeto funcionário são definidos com os valores dos valores recém-copiados.
- 00:20:00 Neste vídeo, o instrutor percorre as três regras para criar construtores em C++. A primeira regra é que um construtor tem o mesmo nome da classe à qual pertence, a segunda é que um construtor deve ser público e a terceira é que um construtor deve ser acessível. Ao criar um construtor, é importante ter em mente as regras descritas neste vídeo. Se um construtor não estiver seguindo uma dessas regras, um erro será gerado.
- 00:25:00 Neste vídeo, o instrutor explica os fundamentos da programação orientada a objetos, incluindo os conceitos de classes, objetos e métodos. Ele então descreve quatro princípios-chave da programação orientada a objetos: encapsulamento, abstração, herança e polimorfismo. Por fim, ele explica como implementar esses conceitos em um exemplo de código.
- 00:30:00 Este vídeo apresenta a programação orientada a objetos (OOP) em C++. Uma classe é uma estrutura que encapsula dados e métodos públicos que outras classes podem invocar para acessar e modificar os dados. Para fornecer encapsulamento, os campos de classe são privados e os getters e setters são públicos.
- 00:35:00 Neste vídeo, um instrutor do curso de C++ discute os princípios da programação orientada a objetos (OOP). O instrutor discute como o encapsulamento e a abstração ajudam a ocultar dados complexos por trás de uma interface simplificada. O instrutor também discute como as regras de validação podem ser aplicadas aos métodos setter de propriedades privadas.
- 00:40:00 Neste vídeo, o apresentador explica como a programação orientada a objetos (OOP) pode tornar o desenvolvimento de software mais simples, ocultando a complexidade dos usuários. Eles usam um exemplo de smartphone para ilustrar como OOP pode fazer um processo complexo parecer simples. Eles então demonstram como criar um contrato que faz com que um lado de um sistema pareça simples enquanto esconde a complexidade do sistema do usuário.
- 00:45:00 Este vídeo explica o conceito de programação orientada a objetos (OOP) em C++. O vídeo discute como criar uma classe abstrata que requer implementação para uma função virtual e como testar a função para ver se um determinado funcionário pode obter uma promoção.
- 00:50:00 Neste vídeo, o autor é promovido e, se essa pessoa tiver menos de 30 anos, essa pessoa não será promovida. Isso nos permite implementar um contrato que é na verdade uma classe abstrata e essa classe abstrata ou esse contrato tem apenas uma regra e essa regra é essa função virtual pura aqui que é chamada de solicitação de promoção. Então, seja qual for a classe que assinar este contrato, seja qual for a classe que herdar deste funcionário abstrato, que é esta classe aqui, terá que fornecer implementação para este método aqui. Nós testamos e, como você pode ver, eu não consegui promoção e John conseguiu, então essa é a ideia de abstração. E esse método de solicitação de promoção é apenas aquele botão que mencionamos no início deste capítulo. O terceiro princípio da programação orientada a objetos sobre o qual quero falar é chamado de herança. A ideia de herança é a seguinte: existe essa classe base também conhecida como superclasse ou classe pai e depois existe a classe derivada também conhecida como classe filha ou subclasse.
- 00:55:00 Neste vídeo, um instrutor do curso de C++ demonstra como a programação orientada a objetos funciona criando uma classe derivada de uma classe base existente. As propriedades da classe base são então herdadas pela classe derivada, que também obtém suas próprias propriedades específicas para a classe do desenvolvedor.
- 01:00:00 Neste vídeo, o instrutor discute como a programação orientada a objetos funciona em C++. Ele explica como uma classe de desenvolvedor herda de uma classe de funcionário e como o construtor da classe de funcionário pode ser usado para inicializar certas propriedades da classe de desenvolvedor. O instrutor então mostra como um método pode ser criado na classe do desenvolvedor para testar se as propriedades foram definidas corretamente. Finalmente, ele demonstra como fechar a classe de desenvolvedor.
- 01:05:00 Neste vídeo, o instrutor discute os conceitos de herança e polimorfismo da programação orientada a objetos (OOP). Ele demonstra como usar esses conceitos para resolver um problema com um exemplo de código. Por fim, o instrutor demonstra como criar uma classe herdada de outra classe.
- 01:10:00 Este vídeo fornece uma breve visão geral da programação orientada a objetos (OOP) em C++. O vídeo explica como criar uma classe de professor que herda de uma classe de funcionário e implementa uma função de preparação de aula. O vídeo também discute alguns dos problemas que podem surgir ao criar e usar classes OOP e como resolvê-los.
- 01:15:00 Neste vídeo, o instrutor explica o conceito de programação orientada a objetos (OOP) em C++. Polimorfismo refere-se à capacidade de um objeto ou método de ter muitas formas. Um uso comum de polimorfismo na programação é quando uma referência de classe pai é usada para se referir a um objeto de uma classe filha. Este exemplo demonstra como o polimorfismo funciona retornando à função principal e invocando o novo método de trabalho nas classes desenvolvedor e professor, ambas herdadas da classe funcionário.
- 01:20:00 Este vídeo aborda os fundamentos da programação orientada a objetos em C++. A primeira parte do vídeo aborda a história da programação orientada a objetos e como ela difere de outros paradigmas de programação. A segunda parte do vídeo explica como criar um ponteiro para uma classe base e como tornar um método de trabalho virtual em uma classe de funcionário. Por fim, o vídeo demonstra como o ponteiro funciona e como o programa funciona como resultado.
- 01:25:00 Neste vídeo, o instrutor discute o conceito de funções virtuais e polimorfismo em C++. Ele explica que, quando uma função virtual é invocada, a versão mais derivada da função é executada. Isso significa que, se uma função não for implementada nas classes derivadas de uma classe, a classe de desenvolvedor da classe será invocada em seu lugar. Ele também observa que, com o polimorfismo, diferentes tipos de funcionários podem ser tratados como se fossem um grande objeto, permitindo que sejam referenciados com um ponteiro de classe base.
- 01:30:00 Este vídeo apresenta a Programação Orientada a Objetos (OOP) em C++. Ele discute como OOP torna a programação mais organizada e fácil de entender. A apresentadora também recomenda que os espectadores sigam seu canal, codifiquem beleza e se inscrevam lá. Por fim, a apresentadora incentiva os espectadores a deixar comentários sobre seus vídeos.
- 2021.02.02
- www.youtube.com
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Em nosso mundo tecnologicamente avançado, a programação e a ciência da computação tornaram-se disciplinas transformadoras que impulsionam a inovação e moldam a sociedade.
A programação, como uma forma de arte, combina criatividade, lógica e resolução de problemas para criar soluções elegantes e eficientes.
A ciência da computação serve como base científica para a programação, abrangendo teorias, algoritmos e metodologias para o desenvolvimento e implementação de programas de computador. No entanto, a programação em si requer imaginação e engenhosidade. Como um artista de tela em branco, um programador tece linhas de código em algoritmos complexos, criando obras-primas digitais que revolucionam indústrias, simplificam tarefas e aprimoram a experiência do usuário. A programação orientada a objetos (OOP) é um paradigma chave na ciência da computação que permite aos programadores gerenciar a complexidade organizando o código em objetos reutilizáveis e modulares. Ao encapsular dados e comportamento em objetos, os programadores podem criar soluções criativas que são mais fáceis de entender, manter e estender.
A programação vai além da solução de problemas e inclui o design de interfaces amigáveis e experiências envolventes do usuário. Este aspecto combina a sensibilidade artística com o conhecimento técnico. Os programadores projetam a interface do usuário (UI) e a experiência do usuário (UX) usando estética, navegação intuitiva e visuais atraentes para criar software que encanta e cativa os usuários. A arte consiste em combinar perfeitamente funcionalidade com apelo estético, traduzindo recursos complexos em designs intuitivos e visualmente agradáveis. Com OOP, os programadores podem separar tarefas e criar objetos separados que são responsáveis por diferentes aspectos do software. Essa abordagem modular promove a criatividade no design, permitindo que os programadores se concentrem em objetos individuais, suas interações e no comportamento geral do sistema. Usando princípios OOP como herança e polimorfismo, os programadores podem desenvolver software com uma interface intuitiva, interface amigável e estética visualmente atraente.
A engenharia de software, uma disciplina da ciência da computação, enfatiza o aspecto artístico da programação. Abrange todo o ciclo de vida de desenvolvimento de software, desde a coleta de requisitos até a implantação e manutenção. Os engenheiros de software abordam a programação como arquitetos, projetando sistemas e plataformas confiáveis, escaláveis e de fácil manutenção. Eles consideram fatores como modularidade de código, reutilização e padrões de arquitetura para criar soluções de software que combinam funcionalidade e elegância. A arte do desenvolvimento de software é equilibrar restrições técnicas, necessidades do usuário e objetivos de design para criar um software que seja funcional e esteticamente agradável. OOP desempenha um papel fundamental no desenvolvimento de software, fornecendo uma abordagem estruturada para gerenciar a complexidade. A separação do código em classes e objetos permite que os desenvolvedores de software projetem sistemas modulares, reutilizáveis e passíveis de manutenção. Com a abstração e o encapsulamento certos, os desenvolvedores de software podem encontrar um equilíbrio que resulta em um software funcional e elegante.
A arte da programação e da informática vai além do setor de tecnologia, afetando as indústrias e a sociedade como um todo. Da saúde às finanças, da educação ao entretenimento, a programação e a ciência da computação estão revolucionando a maneira como trabalhamos, nos comunicamos e vivemos. Inovações como inteligência artificial, realidade virtual e tecnologia blockchain estão mudando as indústrias e abrindo novos horizontes. Programadores e cientistas da computação estão desempenhando um papel fundamental nesses avanços transformadores, ampliando os limites do que é possível e transformando ideias em realidade. OOP permite aos programadores criar soluções inovadoras que revolucionam diversas áreas. Ao gerenciar a complexidade com a natureza modular e extensível do OOP, os programadores podem desenvolver sistemas complexos, como algoritmos de inteligência artificial, experiências imersivas de realidade virtual e aplicativos blockchain seguros. Esses avanços estão mudando as indústrias, aumentando a produtividade e melhorando a qualidade de vida das pessoas em todo o mundo.
O gerenciamento da complexidade é um aspecto fundamental do desenvolvimento de software. À medida que os sistemas se tornam mais complexos, torna-se necessário usar abordagens eficazes para gerenciar a complexidade e garantir a capacidade de manutenção e escalabilidade.
O paradigma orientado a objetos é uma abordagem poderosa que oferece vantagens significativas no gerenciamento da complexidade. Ao encapsular dados e comportamentos em objetos e usar conceitos como encapsulamento, herança e polimorfismo, o paradigma orientado a objetos fornece uma base sólida para gerenciar a complexidade.
O encapsulamento é um princípio fundamental do paradigma orientado a objetos que promove a associação de dados e métodos dentro de objetos. Esse encapsulamento esconde as complexidades internas de um objeto, expondo apenas as interfaces necessárias para interagir com ele. Ao ocultar detalhes de implementação, o encapsulamento reduz a complexidade de outras partes do sistema, permitindo que os desenvolvedores se concentrem em abstrações de nível superior. Isso promove a modularidade e melhora a legibilidade do código, tornando os sistemas complexos mais fáceis de entender e manter.
A abstração é outro conceito-chave no paradigma orientado a objetos para ajudar a gerenciar a complexidade. Isso permite que os desenvolvedores representem objetos complexos do mundo real como classes, abstraindo detalhes desnecessários. Ao criar classes e interfaces abstratas, os desenvolvedores podem definir comportamentos e atributos comuns que podem ser herdados e implementados por várias subclasses. Essa organização hierárquica de classes permite que os desenvolvedores gerenciem a complexidade dividindo sistemas complexos em componentes menores e mais gerenciáveis. Cada classe se concentra em suas responsabilidades específicas, resultando em uma base de código mais modular e compreensível.
A herança é um poderoso mecanismo fornecido pelo paradigma orientado a objetos que promove a reutilização de código e reduz a redundância. Isso permite que novas classes herdem propriedades e comportamento de classes existentes estabelecendo um relacionamento "é" entre elas. A herança ajuda a gerenciar a complexidade, permitindo que os desenvolvedores definam uma classe base com atributos e comportamentos comuns e, em seguida, criem classes especializadas que herdam dela. Essa organização hierárquica de classes elimina a duplicação de código, reduz a complexidade e melhora a capacidade de manutenção.
O polimorfismo é uma característica chave do paradigma orientado a objetos que permite que objetos de diferentes tipos sejam tratados de forma intercambiável com base em suas interfaces comuns. O polimorfismo simplifica o gerenciamento da complexidade, permitindo que os desenvolvedores escrevam códigos que funcionem com uma abstração de alto nível sem ter que lidar com os detalhes de implementação específicos de cada objeto. Usando o polimorfismo, os desenvolvedores podem criar sistemas mais flexíveis e extensíveis porque novas classes podem ser adicionadas sem afetar o código existente. Isso promove o desenvolvimento modular e escalável, reduzindo a complexidade a longo prazo.
O gerenciamento da complexidade é um aspecto crítico do desenvolvimento de software, e o paradigma orientado a objetos fornece uma estrutura poderosa para essa tarefa.
Por meio de princípios como encapsulamento, abstração, herança e polimorfismo, o paradigma orientado a objetos permite que os desenvolvedores gerenciem efetivamente a complexidade e criem sistemas sustentáveis, escaláveis e modulares. Ao encapsular dados e comportamentos em objetos, abstrair detalhes desnecessários, reutilizar código por meio de herança e usar polimorfismo, o paradigma orientado a objetos oferece uma abordagem abrangente para gerenciar a complexidade. O uso do paradigma orientado a objetos melhora muito o processo de desenvolvimento de software e contribui para a criação de sistemas de software confiáveis e gerenciáveis.
A arte da programação combina princípios científicos com criatividade, resolução de problemas e inovação. É uma disciplina que exige proeza técnica e visão artística. Gerenciar a complexidade com uma abordagem orientada a objetos é essencial na programação, permitindo que os programadores desenvolvam soluções elegantes e eficientes, melhorem a experiência do usuário e causem um impacto duradouro na sociedade.
À medida que a tecnologia avança, o software continuará a moldar nosso mundo digital e impulsionar a inovação futura.