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)
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
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)
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)
É 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
5
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)
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)
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)
Como visto no exercício anterior, Julia permite que uma função retorne múltiplos valores. Isso permite que você envie mais de um resultado ao chamar uma função, tornando o código mais conciso e fácil de entender. Essa funcionalidade é especialmente útil em situações onde você precisa de mais de um resultado, como em operações matemáticas, decomposições, ou processamento de dados.
Para retornar múltiplos valores em Julia, você pode simplesmente separá-los por vírgulas. Aqui está um exemplo simples:
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)