Algoritmo complicado

9 respostas
D

Peoples, estou tentando fazer um algoritmo que resolva o seguinte problema:

Dada uma placa qualquer de um veiculo dizer a qual estado essa uf pertence.

Tentei, tentei, tentei, tentei e num consegui.
Eu até postei no tópico de desafio que tem aqui no GUJ, mas ninguém respondeu.
Se alguem conseguir algum algoritmo eficiente que resolva esse problema e puder postar ai eu agradeço.

para ajudar na criação desse algoritmo vou postar uma tabela com as series inicias e finais de cada estado

Combinação alfanumérica? UF?

AAA 0001 a BEZ 9999 Paraná (PR)

BFA 0001 a GKI 9999 São Paulo (SP)

GKJ 0001 a HOK 9999 Minas Gerais (MG)

HOL 0001 a HQE 9999 Maranhão (MA)

HQF 0001 a HTW 9999 Mato Grosso do Sul (MS)

HTX 0001 a HZA 9999 Ceará (CE)

HZB 0001 a IAP 9999 Sergipe (SE)

IAQ 0001 a JDO 9999 Rio Grande do Sul (RS)

JDP 0001 a JKR 9999 Distrito Federal (DF)

JKS 0001 a JSZ 9999 Bahia (BA)

JTA 0001 a JWE 9999 Pará (PA)

JWF 0001 a JXY 9999 Amazonas (AM)

JXZ 0001 a KAU 9999 Mato Grosso (MT)

KAV 0001 a KFC 9999 Goiás (GO)

KFD 0001 a KME 9999 Pernambuco (PE)

KMF 0001 a LVE 9999 Rio de Janeiro (RJ)

LVF 0001 a LWQ 9999 Piauí (PI)

LWR 0001 a MMM 9999 Santa Catarina (SC)

MMN 0001 a MOW 9999 Paraíba (PB)

MOX 0001 a MTZ 9999 Espírito Santo (ES)

MUA 0001 a MVK 9999 Alagoas (AL)

MVL 0001 a MXG 9999 Tocantins (TO)

MXH 0001 a MZM 9999 Rio Grande do Norte (RN)

MZN 0001 a NAG 9999 Acre (AC)

NAH 0001 a NBA 9999 Roraima (RR)

NBB 0001 a NEH 9999 Rondônia (RO)

NEI 0001 a NFB 9999 Amapá (AP)

NFC 0001 a NGZ 9999 Goiás (GO) 2ª sequência

NHA 0001 a NHT 9999 Maranhão (MA) 2ª sequência

NHU 0001 a NIX 9999 Piauí (PI) 2ª sequência

NIY 0001 a NJW 9999 Mato Grosso (MT) 2ª sequência

NJX 0001 a NLU 9999 Goiás (GO) 3ª sequência

NLV 0001 a NMN 9999 Alagoas (AL) 2ª sequência

NMO 0001 a NNI 9999 Maranhão (MA) 3ª sequência

NNJ 0001 a NNX 9999 Rio Grande do Norte (RN) 2ª sequência

NNY 0001 a NOH 9999 Paraíba (PB) 2ª sequência

NOI 0001 a NPB 9999 Amazonas (AM) 2ª sequência

NPC 0001 a NPQ 9999 Mato Grosso (MT) 3ª sequência

NPR 0001 a NQK 9999 Paraíba (PB) 3ª sequência

NQL 0001 a NRE 9999 Ceará (CE) 2ª sequência

NRF 0001 a NSD 9999 Mato Grosso do Sul (MS) 2ª sequência

NSE 0001 a NTC 9999 Pará (PA) 2ª sequência

NTD 0001 a NTX 9999 Bahia (BA) 2ª sequência

NTY 0001 a NUL 9999 Mato Grosso (MT) 4ª sequência

NUM 0001 a NVF 9999 Ceará (CE) 3ª sequência

NVG 0001 a NVN 9999 Sergipe (SE) 2ª sequência

NVO 0001 a NWR 9999 Goiás (GO) 4ª sequência

NWS 0001 a NXT 9999 Sequências ainda não definidas

NXU 0001 a NXW 9999 Pernambuco (PE) 2ª sequência

NXX 0001 a PED 9999 Sequências ainda não definidas

PEE 0001 a PFQ 9999 Pernambuco (PE) 3ª sequência[5]

PFR 0001 a ZZZ 9999 Sequências ainda não definidas

9 Respostas

ViniGodoy

Pois é, foi por isso que eu me posicionei contra a colocar lição de casa como desafio.

Uma dica. Despreze os números. Como eles sempre vão de 0001 até 9999, não tem pq considerá-los.

Quanto às letras, é bem fácil transforma-las em um número. Dê uma lida:
http://www.klickeducacao.com.br/materia/20/display/0,5912,POR-20-88-946-5585,00.html

E pense numa base onde ao invés de números, você tem letras. Aí é só testar os intervalos.

Outra possibilidade é organizar as letras numa árvore binária de pesquisa.

D

amigão, isso nem bera de ser um exercicio de casa. Eu que tive a idéia de fazer um algoritmo para isso, mas não estou conseguindo. Sobre o desprezo dos números eu já sei, e a questão do intervalo que está complicado para mim, pois não estou conseguindo resolver.
Já fiz alguns algoritmos, mas furam em determinadas placas.

ViniGodoy

Está em anexo.

Testei com algumas placas, como a do meu carro e aparentemente funciona (talvez eu tenha errado alguma coisa no cadastro das sequências).

O grande segredo, como eu já tinha comentado, está em gerar uma representação decimal do número da placa. Faço isso convertendo a base das letras na base decimal, e somando com os números do final (meu algorítmo considera os números). Eis o trecho de código que faz a mágica (na classe Placa):

/**
	 * Gera uma representação decimal da placa que vai de 0 (AAA 0000) até 175.769.999 (ZZZ 9999).
	 * 
	 * @return Uma representação decimal da placa.
	 */
	public int getRepresentacaoNumerica() {
		int numero = 0;

		for (int i = 0; i < 3; i++)
			numero = 26 * numero + (valor.charAt(i) - 65);

		numero *= 10000;
		numero += Integer.parseInt(getNumeros());

		return numero;
	}

A multiplicação do número por 26 ocorre pq existem 26 letras no alfabeto.
A subtração do char por 65 converte a letra A (65 na tabela ascii) em 0, a B em 1, e assim por diante.

Depois disso, bastou criar um intervalo para cada sequência de placas e comparar com >= e <=.

Veja (classe Sequencia.java), esse é o código que testa se uma placa está ou não dentro da sequência:

public boolean contemPlaca(Placa placa) {
   int numero = placa.getRepresentacaoNumerica();
   return numero >= placaInicial.getRepresentacaoNumerica() && 
          numero <= placaFinal.getRepresentacaoNumerica();
}
ViniGodoy

Se o meu algoritmo furar nessa placas, seria interessante você montar um teste unitário com as placas que furam e postar aqui.
Mas acredito que ele só vá furar caso os números do governo estejam furados também.

D

Very Good! muito interessante esse seu método de resolver esse desafio. Consegui consertar o meu, só que ficou bem “lusitano”, mas valeu pelo seu algoritmo, espero que outras pessoas postem para que possamos ver as diversas maneiras. Vou postar o meu quando chegar em casa, no momento estou no trabalho.

C

Perfeito o algoritmo em JAVA mas eu estou agora tentando fazer em C++
mas ta complicado, tem como me ajudar??
Pois não consigo converter as letras em números para depois compara-las em sequencia…!

ViniGodoy

claude754:
Perfeito o algoritmo em JAVA mas eu estou agora tentando fazer em C++
mas ta complicado, tem como me ajudar??
Pois não consigo converter as letras em números para depois compara-las em sequencia…!

No C++ toda variável char é, automaticamente, um número. Por exemplo, a letra A é o número 65:

int valor = static_cast<int>('A'); std::cout << valor << std::endl;

C

Se eu usar esse codigo:

#include <iostream> using namespace std; int main() { for ( char i = 65; i < 90; i++ ) { cout << (char) i << "[" << (int) i << "]" << endl; } return 0; }

ele irá me mostrar qual o valor decimal de cada letra, mas como vou fazer para identificar as 3 primeiras sem que ele pegue as 3 juntos?? tipo AAA separadas para depois usar os números para fazer uma comparação para identificar de qual cidade é?

ViniGodoy

Veja se isso te dá alguma idéia:

#include <string>
#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
    std::string texto = "Hello world!";
    for (int i = 0; i < texto.size(); ++i) {
        cout << texto[i] << endl;
    }
    return 0;
}
Criado 20 de novembro de 2010
Ultima resposta 11 de fev. de 2014
Respostas 9
Participantes 3