Pesquisar este blog

Livros Recomendados

quarta-feira, 24 de março de 2021

URI (BEECROWD) - 2651 - Link Bolado - Strings - C e C++

Plataforma: URI (BEECROWD)


Problema2651

Linguagens: C e C++

Enunciado:
Link é um herói famoso e por isso recebe diversas cartas de seus fãs. Porém mesmo sendo famoso, todos continuam o chamando de Zelda.
Por causa disso Link está muito bolado, tão bolado que sempre que recebe uma carta ele confere como o seu fã se referiu a ele na carta, e caso ele perceba o trecho "zelda" no nome ele fica bolado e joga a carta fora.
Sua tarefa é determinar se Link ficará bolado com a forma que seu fã o chamou na carta ou não.

Solução:

Nesse post eu mostro três soluções, duas delas feitas em C e uma em C++.

Na primeira solução em C a estratégia foi utilizar uma função para passar toda cadeia de caracteres para uppercase (maiúscula) com a função toupper da biblioteca ctype.h. Para percorrer a string, comecei no índice zero e fui até strlen(z), considerando que z é a minha cadeia de caracteres. A função strlen está disponível na biblioteca string.h.

Sabendo disso, bastaria então comparar se a cadeia de caracteres informada coincidia com "ZELDA". Isso foi feito com a função strstr, da biblioteca string.h. Depois, a ação necessária era imprimir o texto correspondente.

Eu utilizei o operador ternário direto no printf, verificando se o retorno de strstr comparando z com "ZELDA" daria nulo (valor NULL). Se você preferir pode criar um if, eu achei que assim ficava mais fácil de escrever e que não comprometeria a legibilidade. O que você acha?

#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main() {
    
    char z[100010];
    int i;
    
    while (scanf("%s ", z) != EOF) {
        
        for (i = 0; i < strlen(z); i++)
            z[i] = toupper(z[i]);
            
        printf("Link %s\n", (strstr(z, "ZELDA") != NULL? "Bolado" : "Tranquilo"));
    }

    return 0;
}

A estratégia da segunda solução (ou solução alternativa, como gosto de chamar) é parecida com a primeira, mas utilizei algumas funções diferentes. Ao obter o texto informado, passei ele para letra maiúscula analisando seu código ASCII. Se fosse letra minúscula, passaria para maiúscula, e todos os outros caracteres permanecem como estão. Caso encontre "ZELDA", imprime "Bolado", senão imprime "Tranquilo". A função getTam, utilizada para obter o tamanho da cadeia de caracteres, é uma versão similar ao que já existe em strlen, na biblioteca string.h. Apesar de não usar strlen nesta solução, foi necessário incluir esta biblioteca para fazer uso da função strstr, que verifica se há uma string dentro de outra string. Nesse ponto a diferença foi que criei minha própria strlen, mas chamei de getTam.

Portanto, o que essa solução traz de diferente é o uso do código ASCII para analisar cada caractere e transformá-lo em uppercase quando for o caso e a criação da função getTam, utilizada no lugar da função pronta strlen, disponível em string.h. Ah, não esqueça de incluir o "\n" no seu printf, pois é necessário quebrar a linha sempre ao final do seu texto.

E aí, conseguiu entender?

#include <stdio.h>
#include <string.h>

size_t getTam(const char *str) {
    size_t len;
    for (len = 0; ; ++len)
        if (!str[len])
            return len;
}

int main() {
    
    char z[100010];
    unsigned int i, cod;
    size_t tam;
    
    while (scanf("%s ", z) != EOF) {
        
        tam = getTam(z);
        for (i = 0; i < tam; i++) {
            cod = z[i];
            z[i] -= (cod <= 122 && cod >= 97? 32 : 0);
        }
            
        printf("Link %s\n", (strstr(z, "ZELDA") != NULL? "Bolado" : "Tranquilo"));
    }

    return 0;
}

A solução em C++ fica, ao meu ver, bem mais simples. A estratégia foi a mesma: bastava procurar pela expressão "ZELDA" no texto informado. Para evitar problemas com letras maiúsculas e minúsculas, uma alternativa é passar toda expressão digitada para maiúscula e então procurar pelo termo "ZELDA".  Foi isso que eu fiz utilizando transform, passando como parâmetros o início da string, o fim da string, o início da string e ::toupper. Após essa transformação, se a minha string tiver "ZELDA" (e isso foi feito em (z.find(s) != std::string::npos), exibe "Bolado", senão, exibe "Tranquilo".

Não esqueça de quebrar a linha após escrever a resposta, o que é feito com std::cout << std::endl; ou acrescentando << endl quando você já está usando um cout e o namespace std.

#include <algorithm>
#include <iostream>

using namespace std;

int main() {
    
    string z;
    const string s = "ZELDA";
    while (getline(cin, z)) {
        transform(z.begin(), z.end(), z.begin(), ::toupper);
        cout << "Link " << ((z.find(s) != std::string::npos)? "Bolado" : "Tranquilo") << endl;
    }

    return 0;
}

Nenhum comentário:

Postar um comentário

Postagem em destaque

URI (BEECROWD) - 2158 - Helping Uncle Cláudio (Ajudando o Tio Cláudio) - Matemática - C, C++ e Haskell

Buenas! Estou aqui mais uma vez para resolver um problema de Matemática! Agora tenho resolvido alguns dessa categoria, pra que vocês possam ...

Postagens mais visitadas