Nesta aula, vamos explorar funções que manipulam strings e criar testes para verificar sua correção. Em algumas funções, vamos notar que há diversas formas de se obter o mesmo resultado
Concatenação de letras¶
A primeira função concatena concatena as primeiras duas e as últimas duas letras de uma string.
function concatena(s::String)::String
if length(s) < 2
return "Erro: tamanho da string menor do que 2"
end
resposta = s[1:2]*s[end-1:end]
return resposta
endconcatena (generic function with 1 method)Awui utulizamos s[1:2] para obter as duas primeiras letras de s, que é uma forma mais concisa de acessar mais de um índice de um objeto. Alternativamente, poderíamos acessar esses dois índices separadamente com o comando s[1]*s[2].
Para verificar se a função está funcionando corretamente, podemos utilizar o seguinte teste:
using Test
function testeConcatena()
@test concatena("Ola Bom Dia") == "Olia"
@test concatena("oi") == "oioi"
@test concatena("tre") == "trre"
@test concatena("a") == "Erro: tamanho da string menor do que 2"
@test concatena("a123") == "a123"
endtesteConcatena (generic function with 1 method)Inversão de String¶
Devemos criar uma função que interte uma string, retornando os caracteres na ordem reversa.
function inverte(s::String)::String
# Inicializamos uma string vazia
inversa=""
# Intervalo de lenght(s) até 1, a passos de -1
for i in length(s):-1:1
# Concatena cada caractere na ordem inversa
inversa*=s[i]
end
return inversa
endinverte (generic function with 1 method)Para obter o resultado que desejamos, fazemos um laço for que itera do último índice da string, representado por length(s), até o primeiro, concatenando os caracteres nessa ordem na string de retorno.
O laço é configurado para decrementar o índice a cada iteração, especificando -1 como passo. Isso nos permite acessar cada caractere da string de trás para frente. E em cada iteração, concatenamos o caractere atual, s[i], à string inversa. Dessa forma, os caracteres são adicionados na ordem inversa.
Agora podemos criar uma função de teste para verificar o funcionamento da nossa função inverte.
using Test
function testeInverte()
@test inverte("123") == "321"
@test inverte("x") == "x"
@test inverte("SOS") == "SOS"
@test inverte("tres") == "sert"
endtesteInverte (generic function with 1 method)Função reverse¶
É interessante notar que Julia já fornece uma função chamada reverse, que pode ser utilizada para inverter tanto vetores quanto strings. Por exemplo:
reversa = reverse("exemplo")"olpmexe"Neste exemplo, a função reverse recebe como parâmetro apenas o objeto a ser invertido, mas no caso de vetores, podemos ainda informar exatamente o intervalo que desejamos que seja invertido.
vetor = [1, 2, 3, 4, 5]
reversa = reverse(vetor, 2, 4)5-element Vector{Int64}:
1
4
3
2
5Modificação de String¶
A terceira função modifica altera uma string que termina com “ing” para adicionar “ly” ou, caso contrário, adiciona “ing”.
function modifica(s::String)::String
if length(s) < 3
return "Erro: tamanho da string menor do que 3"
end
if s[end-2:end] == "ing"
s = s*"ly"
else
s = s*"ing"
end
return s
endmodifica (generic function with 1 method)Neste exemplo, verificamos manualmente os últimos três caracteres da string s. No entanto, Julia oferece uma função mais prática e legível chamada endswith, que podemos usar para simplificar essa verificação.
function modifica(s::String)::String
if length(s) < 3
return "Erro: tamanho da string menor do que 3"
end
if endswith(s, "ing")
s = s*"ly"
else
s = s*"ing"
end
return s
endmodifica (generic function with 1 method)Vamos então escrever o teste que verifica o correto funcionamento das funções anteriores
using Test
function testaModifica()
@test modifica("doing") == "doingly"
@test modifica("sing") == "singly"
@test modifica("run") == "runing"
@test modifica("talk") == "talking"
endtestaModifica (generic function with 1 method)Rearranjo de letras¶
A segunda função rearranja recebe uma string e devolve uma string que contém as letras minúsculas primeiro, seguidas pelas letras maiúsculas.
Podemos verificar se uma letra é maiúscula ou minúscula usando a tabela ASCII, que codifica caracteres em números inteiros. Na tabela, as letras maiúsculas estão no intervalo de 65 a 90, e as letras minúsculas no intervalo de 97 a 122.
Para saber mais sobre a tabela ASCII você pode acessar essa página.
function rearranja(s::String)::String
maiusculos=""
minusculos=""
for i in 1:length(s)
if Int(s[i]) >= 65 && Int(s[i]) <= 90
maiusculos = maiusculos*s[i]
elseif Int(s[i]) >= 97 && Int(s[i]) <= 122
minusculos = minusculos*s[i]
end
end
return minusculos*maiusculos
endrearranja (generic function with 1 method)Uma abordagem mais legível é utilizar as funções islowercase e isuppercase, que verificam se uma letra é minúscula ou maiúscula, respectivamente.
function rearranja(s::String)::String
maiusculos=""
minusculos=""
for i in 1:length(s)
if isuppercase(s[i])
maiusculos = maiusculos*s[i]
elseif islowercase(s[i])
minusculos = minusculos*s[i]
end
end
return minusculos*maiusculos
endrearranja (generic function with 1 method)Podemos então escrever o teste para nossas funções.
using Test
function testaRearranja()
@test rearranja1("PaRaLelO") == "aaelPRLO"
@test rearranja1("ELEfantE") == "fantELEE"
@test rearranja1("Olá") == "lO"
@test rearranja1("13La2") == "aL"
@test rearranja2("PaRaLelO") == "aaelPRLO"
@test rearranja2("ELEfantE") == "fantELEE"
@test rearranja2("Olá") == "láO"
@test rearranja2("13La2") == "aL"
endtestaRearranja (generic function with 1 method)Encontrar a maior palavra¶
Nossa última função deve receber uma lista de palavras e retornar a maior delas, junto de seu tamanho.
function maior_palavra(vetor::Vector{String})
# Inicialmente, a maoior palavra que encontramos é uma string vazia
maior_palavra = ""
maior_tamanho = 0
for palavra in vetor
# Verifica se a palavra atual é maior que a maior encontrada até agora
if length(palavra) > maior_tamanho
maior_palavra = palavra
maior_tamanho = length(palavra)
end
end
return maior_palavra, maior_tamanho
endmaior_palavra (generic function with 1 method)Apesar de parecer correto, esse código não lida com o caso de haver mais de uma palavra com o maior tamanho. Como por exemplo:
vetor = ["boa", "bem", "oi"]
maior_palavra(vetor)("boa", 3)Nesse caso, apenas a palavra “boa” será retornada, mesmo que “bem” tenha o mesmo tamanho. Para consertar a função devemos alterar a variável em que guardamos a maior palavra, para que possamos armazenar mais de uma palavra, para isso vamos usar um vetor de strings.
function maiores_palavras(vetor::Vector{String})
maiores_palavras = String[]
maior_tamanho = 0
for palavra in vetor
# Se a palavra é maior do que o maior tamanho salvo,
# então todas as palavras que estão no vetor maior_palavra são menores do que a palavra atual
if length(palavra) > maior_tamanho
# Limpa o vetor e salva a palavra atual
maiores_palavras = String[]
push!(maiores_palavras, palavra)
maior_tamanho = length(palavra)
# Se é igual ao tamanho salvo, então é do mesmo tamanho que as palavras já salvas no vetor maiores_palavras,
# apenas damos push na palavra atual
elseif length(palavra) == maior_tamanho
push!(maiores_palavras, palavra)
end
end
return maiores_palavras, maior_tamanho
endmaiores_palavras (generic function with 1 method)Assim podemos escrever testes para esta última função .
using Test
function testeMaioresPalavras()
vetor1 = ["gato", "elefante", "cachorro"]
@test maiores_palavras(vetor1) == (["elefante", "cachorro"], 8)
vetor2 = ["a", "ab", "abc"]
@test maiores_palavras(vetor2) == (["abc"], 3)
vetor3 = ["bem", "boa", "bom", "oi"]
@test maiores_palavras(vetor3) == (["bem", "boa", "bom"], 3)
vetor4 = ["", " ", "teste"]
@test maiores_palavras(vetor4) == (["teste"], 5)
vetor5 = String[]
@test maiores_palavras(vetor5) == ([], 0)
vetor6 = ["a", "ab", "abc", "xyz", "xy"]
@test maiores_palavras(vetor6) == (["abc", "xyz"], 3)
endtesteMaioresPalavras (generic function with 1 method)Retorno de múltiplos valores¶
Como visto no exercício anterior, Julia permite que uma função retorne múltiplos valores. Isso é útil quando você precisa de mais de um resultado ao chamar uma função, como em operações matemáticas, decomposições ou processamento de dados.
Para retornar múltiplos valores em Julia, basta separá-los por vírgulas, como no exemplo abaixo:
function troca(a,b)
aux = a
a = b
b = aux
return a, b
endtroca (generic function with 1 method)Ao chamar essa função, você pode capturar os múltiplos valores retornados em variáveis separadas:
a, b = troca(1, 10)(10, 1)