·
Matemática Aplicada a Negócios ·
Introdução à Computação 2
· 2023/2
Envie sua pergunta para a IA e receba a resposta na hora
Prefere sua atividade resolvida por um tutor especialista?
- Receba resolvida até o seu prazo
- Converse com o tutor pelo chat
- Garantia de 7 dias contra erros
Recomendado para você
25
Slide - Ordenação por Seleção - 2023-2
Introdução à Computação 2
USP
113
Slide - Método da Bolha - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
48
Slide - Estruturas e Ponteiros em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
61
Slide - Subalgoritmos em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
3
Prática 2 - Análise Por Operações Primitivas - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
39
Slide - Algoritmos em Busca de Vetores - 2023-2
Introdução à Computação 2
USP
9
Lista 2 - Algoritmos Recursivos
Introdução à Computação 2
USP
5
Normas Sobre Programação 2022-2
Introdução à Computação 2
USP
Texto de pré-visualização
FAC. DE FILOSOFIA, CIÊNCIAS E LETRAS DE RIBEIRÃO PRETO UNIVERSIDADE DE SÃO PAULO Introdução à Computação II - 5954006 2o semestre 2023 Prof. Renato Tinós 1 PRÁTICA 4: Recursão Considere o problema de descobrir uma senha em um sistema computacional. A senha é composta por n letras maiúsculas (as letras são “ABCDEFGHIJKLMNOPQRSTUVWXYZ”). Considere que é possível verificar se um string s (vetor com n letras) é a senha correta através de um comando “verif s” que é chamado dentro de um programa em C++ e que acessa o sistema computacional e retorna 1 caso a senha esteja correta e 0 caso a senha esteja errada. A chamada do comando (que é dado para o Sistema Operacional Windows) deve ser a seguinte: #include <iostream> #include <cstdlib> #include <string.h> using namespace std; .... char sb[106], s[100]; int sucesso; .... sucesso=system(strcat(strcpy(sb,"verif "),s)); … sendo que s contém o string que será verificado. Um exemplo do uso do comando é dado no programa ex_senha.cpp anexo. FAC. DE FILOSOFIA, CIÊNCIAS E LETRAS DE RIBEIRÃO PRETO UNIVERSIDADE DE SÃO PAULO Introdução à Computação II - 5954006 2o semestre 2023 Prof. Renato Tinós 2 Pede-se: a) Desenvolva uma função utilizando recursão para descobrir qual é a senha correta. Considere que o tamanho n da senha seja digitado pelo usuário (1<n<6). b) Quais são as senhas para n=2, n=3 e n=4? c) Comente sobre a viabilidade e eficiência deste algoritmo baseado em sua complexidade computacional. Para isso, faça a análise assintótica - notação “O” – do tempo do programa desenvolvido. Considere que o comando “verif s” é O(1). PRÁTICA 4: RECURSÃO – RESPOSTAS Questão 1) #include <iostream> #include <cstdlib> #include <string.h> using namespace std; char senhaCorreta[6]; bool verificarSenha(char* s) { if (strcmp(s, senhaCorreta) == 0) { return true; } else { cout << "sh: 1: verif: not found" << endl; return false; } } void descobrirSenha(char* s, int n, int pos = 0) { if (pos == n) { if (verificarSenha(s)) { cout << "Sucesso! Senha: " << s << endl; exit(0); } return; } for (char c = 'A'; c <= 'Z'; ++c) { s[pos] = c; descobrirSenha(s, n, pos + 1); } } int main() { int n; cout << "Entre com o tamanho da senha (maior que 1 e menor que 6): "; cin >> n; cout << "Entre com a senha com " << n << " letras maiusculas: "; cin >> senhaCorreta; char* s = new char[n+1]; s[n] = '\0'; descobrirSenha(s, n); delete[] s; return 0; } Questão 2) A senha correta dependerá da entrada do usuário, sendo que a função de recursão ficará testando o código para todas as 26𝑛 possibilidades, onde 26 são as letras do alfabeto e 𝑛 será o número de caracteres da senha. Para as entradas com 𝑛 = 2, 𝑛 = 3 𝑒 𝑛 = 4, temos: • 𝑛 = 2 → 262 = 676 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 • 𝑛 = 3 → 263 = 17576 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑑𝑖𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 • 𝑛 = 4 → 264 = 456976 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 Questão 3) A abordagem usada neste algoritmo para descobrir a senha correta tem uma complexidade de tempo de: 𝑂(26𝑁) Para esta complexidade de tempo, temos que N é o tamanho da senha. Isso ocorre porque o algoritmo tenta todas as combinações possíveis de letras maiúsculas para uma senha de tamanho N, através da recursão. Se tratando de viabilidade, este algoritmo funcionará e encontrará a senha correta eventualmente, desde que a senha esteja dentro do conjunto de possibilidades que o algoritmo está verificando (neste caso, senhas de tamanho N compostas por letras maiúsculas). Porém, em termos de eficiência, este algoritmo é bastante ineficiente. A complexidade exponencial do tempo significa que o tempo necessário para encontrar a senha correta aumentará muito rapidamente à medida que o tamanho da senha aumenta. Por exemplo, para uma senha de tamanho 6, o algoritmo teria que verificar 266 = 308915776 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 Assim, embora este algoritmo seja viável para senhas muito pequenas, ele se torna impraticável e ineficiente para senhas maiores. Métodos mais eficientes, como por exemplo o “ataque de dicionário”, seriam necessários para senhas maiores ou para um conjunto maior de caracteres possíveis na senha.
Envie sua pergunta para a IA e receba a resposta na hora
Recomendado para você
25
Slide - Ordenação por Seleção - 2023-2
Introdução à Computação 2
USP
113
Slide - Método da Bolha - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
48
Slide - Estruturas e Ponteiros em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
61
Slide - Subalgoritmos em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
3
Prática 2 - Análise Por Operações Primitivas - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
39
Slide - Algoritmos em Busca de Vetores - 2023-2
Introdução à Computação 2
USP
9
Lista 2 - Algoritmos Recursivos
Introdução à Computação 2
USP
5
Normas Sobre Programação 2022-2
Introdução à Computação 2
USP
Texto de pré-visualização
FAC. DE FILOSOFIA, CIÊNCIAS E LETRAS DE RIBEIRÃO PRETO UNIVERSIDADE DE SÃO PAULO Introdução à Computação II - 5954006 2o semestre 2023 Prof. Renato Tinós 1 PRÁTICA 4: Recursão Considere o problema de descobrir uma senha em um sistema computacional. A senha é composta por n letras maiúsculas (as letras são “ABCDEFGHIJKLMNOPQRSTUVWXYZ”). Considere que é possível verificar se um string s (vetor com n letras) é a senha correta através de um comando “verif s” que é chamado dentro de um programa em C++ e que acessa o sistema computacional e retorna 1 caso a senha esteja correta e 0 caso a senha esteja errada. A chamada do comando (que é dado para o Sistema Operacional Windows) deve ser a seguinte: #include <iostream> #include <cstdlib> #include <string.h> using namespace std; .... char sb[106], s[100]; int sucesso; .... sucesso=system(strcat(strcpy(sb,"verif "),s)); … sendo que s contém o string que será verificado. Um exemplo do uso do comando é dado no programa ex_senha.cpp anexo. FAC. DE FILOSOFIA, CIÊNCIAS E LETRAS DE RIBEIRÃO PRETO UNIVERSIDADE DE SÃO PAULO Introdução à Computação II - 5954006 2o semestre 2023 Prof. Renato Tinós 2 Pede-se: a) Desenvolva uma função utilizando recursão para descobrir qual é a senha correta. Considere que o tamanho n da senha seja digitado pelo usuário (1<n<6). b) Quais são as senhas para n=2, n=3 e n=4? c) Comente sobre a viabilidade e eficiência deste algoritmo baseado em sua complexidade computacional. Para isso, faça a análise assintótica - notação “O” – do tempo do programa desenvolvido. Considere que o comando “verif s” é O(1). PRÁTICA 4: RECURSÃO – RESPOSTAS Questão 1) #include <iostream> #include <cstdlib> #include <string.h> using namespace std; char senhaCorreta[6]; bool verificarSenha(char* s) { if (strcmp(s, senhaCorreta) == 0) { return true; } else { cout << "sh: 1: verif: not found" << endl; return false; } } void descobrirSenha(char* s, int n, int pos = 0) { if (pos == n) { if (verificarSenha(s)) { cout << "Sucesso! Senha: " << s << endl; exit(0); } return; } for (char c = 'A'; c <= 'Z'; ++c) { s[pos] = c; descobrirSenha(s, n, pos + 1); } } int main() { int n; cout << "Entre com o tamanho da senha (maior que 1 e menor que 6): "; cin >> n; cout << "Entre com a senha com " << n << " letras maiusculas: "; cin >> senhaCorreta; char* s = new char[n+1]; s[n] = '\0'; descobrirSenha(s, n); delete[] s; return 0; } Questão 2) A senha correta dependerá da entrada do usuário, sendo que a função de recursão ficará testando o código para todas as 26𝑛 possibilidades, onde 26 são as letras do alfabeto e 𝑛 será o número de caracteres da senha. Para as entradas com 𝑛 = 2, 𝑛 = 3 𝑒 𝑛 = 4, temos: • 𝑛 = 2 → 262 = 676 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 • 𝑛 = 3 → 263 = 17576 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑑𝑖𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 • 𝑛 = 4 → 264 = 456976 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 Questão 3) A abordagem usada neste algoritmo para descobrir a senha correta tem uma complexidade de tempo de: 𝑂(26𝑁) Para esta complexidade de tempo, temos que N é o tamanho da senha. Isso ocorre porque o algoritmo tenta todas as combinações possíveis de letras maiúsculas para uma senha de tamanho N, através da recursão. Se tratando de viabilidade, este algoritmo funcionará e encontrará a senha correta eventualmente, desde que a senha esteja dentro do conjunto de possibilidades que o algoritmo está verificando (neste caso, senhas de tamanho N compostas por letras maiúsculas). Porém, em termos de eficiência, este algoritmo é bastante ineficiente. A complexidade exponencial do tempo significa que o tempo necessário para encontrar a senha correta aumentará muito rapidamente à medida que o tamanho da senha aumenta. Por exemplo, para uma senha de tamanho 6, o algoritmo teria que verificar 266 = 308915776 𝑝𝑜𝑠𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑𝑒𝑠 𝑑𝑒 𝑠𝑒𝑛ℎ𝑎 Assim, embora este algoritmo seja viável para senhas muito pequenas, ele se torna impraticável e ineficiente para senhas maiores. Métodos mais eficientes, como por exemplo o “ataque de dicionário”, seriam necessários para senhas maiores ou para um conjunto maior de caracteres possíveis na senha.