Pesquisar este blog

Livros Recomendados

Mostrando postagens com marcador 1272. Mostrar todas as postagens
Mostrando postagens com marcador 1272. Mostrar todas as postagens

terça-feira, 11 de abril de 2023

URI (BEECROWD) - 1272 - Hidden Message (Mensagem Oculta) - Strings - Haskell

Olá!

Aqui vai mais um novo post!

Dessa vez vou resolver um problema da categoria Strings do Beecrowd. Esse problema é o "Mensagem Oculta", ou Hidden Message.

Veja abaixo como eu resolvi este problema!

Ah, só mais um pedido: ajude o blog! PIX: 6d8bc7a8-5d74-493a-ab7a-3515baf35956


Plataforma: URI (BEECROWD)

Problema1272

Enunciado:
Textos podem conter mensagens ocultas. Neste problema a mensagem oculta em um texto é composto pelas primeiras letras de cada palavra do texto, na ordem em que aparecem. É dado um texto composto apenas por letras minúsculas ou espaços. Pode haver mais de um espaço entre as palavras. O texto pode iniciar ou terminar em espaços, ou mesmo conter somente espaços.

Linguagem: Haskell


Solução: 

A estratégia utilizada foi ler cada linha e separar cada palavra (expressão até encontrar um espaço em branco) com a função words. Para cada palavra, executa a função que obtém o primeiro caractere dela (head). Isso é feito para cada palavra gerada por meio de uma função de alta ordem chamada map. O código fica da seguinte forma:

main :: IO ()
main = do
   n <- readLn :: IO Int
   reading n

reading :: Int -> IO ()
reading n = do
   if n == 0
      then return ()
      else do
         line <- getLine
         putStrLn (map head (words line))
         reading (n-1)


imprimo sempre o caractere imediatamente após um espaço em branco.

#include <iostream>
#include <cctype>

using namespace std;

int main() {
    
    int n;
    string linha;
    cin >> n;
    cin.ignore();
    while (n--) {
        getline(cin, linha);
        
        if (isalpha(linha[0]))
            cout << linha[0];
        for (int i = 1; i < linha.size(); i++) {
            if (linha[i] != ' ') {
                while (linha[i] == ' ')
                    i++;
            }
            if (isalpha(linha[i]) && linha[i-1] == ' ')
                cout << linha[i];
        }
        cout << endl;
    }

    return 0;
}

Solução alternativa:

Há várias soluções possíveis. Aqui, embora a ideia seja muito parecida, utilizei composição de funções e a mônada replicateM.

As linhas foram lidas com replicateM, que replica o comando getLine n vezes.

O comando de saída putStrLn intercala os resultados com \n, ou seja, exibe um resultado por linha. O resultado é o mapeamento da função (map head . words) aplicado em lines, ou seja, obtém-se o primeiro caractere de cada palavra de cada linha.

import Control.Monad (replicateM)
import Data.List (intercalate)

main :: IO ()
main = do
  n <- readLn :: IO Int
  lines <- replicateM n getLine
  putStrLn (intercalate "\n" (map (map head . words) lines))

terça-feira, 2 de fevereiro de 2021

URI (BEECROWD) - 1272 - Mensagem Oculta - Strings - C e C++

Resolvi aqui o problema Mensagem Oculta. Trago aqui duas soluções em C++ e uma em C. Este é um problema da categoria strings do Beecrowd. Bora conferir as respostas?

Plataforma: URI (BEECROWD)

Problema1272

Enunciado:
Textos podem conter mensagens ocultas. Neste problema a mensagem oculta em um texto é composto pelas primeiras letras de cada palavra do texto, na ordem em que aparecem. É dado um texto composto apenas por letras minúsculas ou espaços. Pode haver mais de um espaço entre as palavras. O texto pode iniciar ou terminar em espaços, ou mesmo conter somente espaços.

Linguagens: C e C++


Solução: 

Existem várias estratégias para este problema. Veja abaixo.

Código em C:

Aqui eu itero as palavras com strtok utilizando o espaço em branco como delimitador, assim preciso apenas imprimir o primeiro caractere da palavra enquanto ela for diferente de NULL.

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

int main() {
    
    int n;
    char linha[60];
    const char delimitador[2] = " ";
    scanf("%i ", &n);
    while (n--) {
        scanf ("%[^\n]%*c", linha);
        char *termo;
        
        termo = strtok(linha, delimitador);
        
        while (termo != NULL) {
            printf("%c", termo[0]);
            termo = strtok(NULL, delimitador);
        }
        printf("\n");
    }

    return 0;
}

Código em C++:
Nesta solução eu imprimo o primeiro caractere da linha, se ele for alfanumérico, e depois procuro e imprimo sempre o caractere imediatamente após um espaço em branco.

#include <iostream>
#include <cctype>

using namespace std;

int main() {
    
    int n;
    string linha;
    cin >> n;
    cin.ignore();
    while (n--) {
        getline(cin, linha);
        
        if (isalpha(linha[0]))
            cout << linha[0];
        for (int i = 1; i < linha.size(); i++) {
            if (linha[i] != ' ') {
                while (linha[i] == ' ')
                    i++;
            }
            if (isalpha(linha[i]) && linha[i-1] == ' ')
                cout << linha[i];
        }
        cout << endl;
    }

    return 0;
}

Solução alternativa em C++:

Cada linha é percorrida procurando por letras. Caso na posição anterior não seja letra, então a letra atual é adicionada a string final.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
using namespace std;
 
int main() {
 string line;
 int n;
 cin >>n;
 getline(cin, line);
 while(n--){
  string final_str = "";
  getline(cin, line);
  bool last_space = true;
  for(int i=0; i<line.length();i++){
   if(last_space==true and (line[i]>='a' and line[i]<='z')){
    last_space = false;
    final_str += line[i];
   }
   if(!(line[i]>='a' and line[i]<='z')){
    last_space = true;
   }
  }
  cout << final_str << endl;
 }
 
    return 0;
}

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