Comparar matrizes

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

elaineosm
Usuário Nível 1
Usuário Nível 1
Mensagens: 21
Registrado em: 04 Jul 2019 13:14
Localização: BM/RJ

Comparar matrizes

Mensagem por elaineosm »

Boa noite !

Existe alguma função do harbour que compare duas matrizes ou é preciso fazer isto manualmente? ex:
Tenho duas matrizes com informações que preciso comparar entre elas. Se houver valor diferente entre valor1 x valor1 ou valor2 x valor2 e assim sucessivamente, vou armazenar a "linha" inteira do vetor2 em um terceiro vetor.
Desse jeito funcionar, mas queria saber se existe algo mais simples já pronto.

vetor1 = {}, vetor2 = {}
alt = .t.
aadd(vetor1, { "valor1", "valor2", "valor3", "valor4", "valor5})
aadd(vetor2, { "valor1", "valor2", "valor3", "valor4", "valor5})

for N=1 to len(V1)
if V1[N][1] == V2[N][1]
if V1[N][2] == V2[N][2]
if V1[N][3] == V2[N][3]
alt = .f.
endif
endif
endif

if (alt)
aadd(vetor3, {V2[N][1], V2[N][2], V2[N][3]) // se for diferente adiciono os valores do vetor 2
endif

next

return .t.
Ranier
Usuário Nível 2
Usuário Nível 2
Mensagens: 80
Registrado em: 02 Abr 2019 09:01
Localização: Goiania/Goias

Comparar matrizes

Mensagem por Ranier »

elaineosm escreveu: Existe alguma função do harbour que compare duas matrizes ou é preciso fazer isto manualmente? ex:
Tenho duas matrizes com informações que preciso comparar entre elas. Se houver valor diferente entre valor1 x valor1 ou valor2 x valor2 e assim sucessivamente, vou armazenar a "linha" inteira do vetor2 em um terceiro vetor.
Desse jeito funcionar, mas queria saber se existe algo mais simples já pronto.
Acredito que não exista tal função e que teria que ser feito manualmente.

Mas tem alguns probleminhas no seu código.

Código: Selecionar todos

local vetor1 := { "valor1", "valor2", "valor3", "valor4", "valor5}
local vetor2 := { "valor1", "valor2", "valor3", "valor4", "valor5}
local alt := .f.

for N := 1 to len(V1)
   if V1[N][1] != V2[N][1] .and. V1[N][2] != V2[N][2] .and. V1[N][3] != V2[N][3]
      aadd(vetor3, {V2[N][1], V2[N][2], V2[N][3])  // se for diferente adiciono os valores do vetor 2 
      alt := .t.
   endif
next

return alt
alt tem que começar com false.
o teste principal vc tem que fazer o usando short-cut da lógica booleana, economizando ciclos da cpu.
o return tem q ser a variável alt
elaineosm
Usuário Nível 1
Usuário Nível 1
Mensagens: 21
Registrado em: 04 Jul 2019 13:14
Localização: BM/RJ

Comparar matrizes

Mensagem por elaineosm »

Bom dia!
Pensei em fazer as condições separadamente ao invés de linear, porque - por exemplo - se logo no primeiro ou segundo if a condição for falsa, a cpu não terá que processar as demais condições. Se eu colocar tudo linear, a cpu vai checar todas as condições, mesmo que já na primeira for falsa. Entendeu o motivo?
Ranier
Usuário Nível 2
Usuário Nível 2
Mensagens: 80
Registrado em: 02 Abr 2019 09:01
Localização: Goiania/Goias

Comparar matrizes

Mensagem por Ranier »

elaineosm escreveu:Bom dia!
Pensei em fazer as condições separadamente ao invés de linear, porque - por exemplo - se logo no primeiro ou segundo if a condição for falsa, a cpu não terá que processar as demais condições. Se eu colocar tudo linear, a cpu vai checar todas as condições, mesmo que já na primeira for falsa. Entendeu o motivo?
Acho que você não sabe o que é "shortcut" de lógica booleana.
Se usar o .and., no primeiro teste que falhar, o compilador para de imediato e não faz os testes seguintes.
Se usar o .or. ai sim, todos os testes são feitos.
Isso funciona para todas linguagens não só para o xBase.
elaineosm
Usuário Nível 1
Usuário Nível 1
Mensagens: 21
Registrado em: 04 Jul 2019 13:14
Localização: BM/RJ

Comparar matrizes

Mensagem por elaineosm »

Acontece que se um deles for diferente, deve ser armazenado. Não necessariamente todos. E ai neste caso teria que ser o .or. ou para comparar usando o ==, não deve adicionar ao vetor caso todos sejam iguais.
Ranier
Usuário Nível 2
Usuário Nível 2
Mensagens: 80
Registrado em: 02 Abr 2019 09:01
Localização: Goiania/Goias

Comparar matrizes

Mensagem por Ranier »

Desculpe, acho que estou falando bobagem.
O teste com .and. é correto, se a troca tiver que ocorrer, se e somente se, todas as condições forem diferentes.
Mas se a troca for ocorrer, caso qualquer uma das condições for diferente, ai sim, o teste tem q ser outro.

seu teste original com "shortcut"

Código: Selecionar todos

if V1[N][1] == V2[N][1] .and. V1[N][2] == V2[N][2] .and. V1[N][3] == V2[N][3]
   alt = .f.
endif
troca, se qualquer dos vetores for diferente

Código: Selecionar todos

if V1[N][1] != V2[N][1] .or. V1[N][2] != V2[N][2] .or. V1[N][3] != V2[N][3]
   aadd(vetor3, {V2[N][1], V2[N][2], V2[N][3])  // se for diferente adiciono os valores do vetor 2 
endif
Realmente aqui o compilador, irá efetuar todos os testes, sempre.

troca, se e semente se, todos os vetores for diferente

Código: Selecionar todos

if V1[N][1] != V2[N][1] .and. V1[N][2] != V2[N][2] .and. V1[N][3] != V2[N][3]
   aadd(vetor3, {V2[N][1], V2[N][2], V2[N][3])  // se for diferente adiciono os valores do vetor 2 
endif
Não sei qual se encaixa melhor no seu caso.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Comparar matrizes

Mensagem por JoséQuintas »

Tem até função no Harbour pra transformar qualquer valor em texto, o que permitiria comparar, mas sem registrar.
? EssaFuncao( array1 ) == EssaFuncao( Array2 )

Sei lá se otimiza alguma coisa assim:

Código: Selecionar todos

FOR EACH aNivel1 IN aArrayPrimeiro
   lEqual := .T.
   FOR EACH aNivel2 IN aNivel1
      lEqual := lEgual .AND. aNivel2 == aArraySegundo[ aNivel1:__EnumIndex ][ aNivel2:__EnumIndex ]
      IF ! lEqual
         EXIT
      ENDIF
   NEXT
   IF ! lEqual
      FOR EACH aNivel2 IN aNivel1
         ? aNivel1:__EnumIndex, aNivel2:__EnumIndex, aNivel2, aArraySegundo[ a_NIvel1:__EnumIndex, aNivel2:__EnumIndex ]
      NEXT
   ENDIF
NEXT
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
elaineosm
Usuário Nível 1
Usuário Nível 1
Mensagens: 21
Registrado em: 04 Jul 2019 13:14
Localização: BM/RJ

Comparar matrizes

Mensagem por elaineosm »

vou testar aqui.
Mt Obg Ranier e J.Quintas
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Comparar matrizes

Mensagem por JoséQuintas »

Talvez fique mais "legível" com nomes mais adequados:

Código: Selecionar todos

FOR EACH aDetalhes IN aArrayPrimeiro
   lEqual := .T.
   FOR EACH xValue IN aDetalhes
      lEqual := lEgual .AND. xValue == aArraySegundo[ aDetalhes:__EnumIndex ][ xValue:__EnumIndex ]
      IF ! lEqual
         EXIT
      ENDIF
   NEXT
   IF ! lEqual
      FOR EACH xValue IN aDetalhes
         ? aDetalhes:__EnumIndex, xValue:__EnumIndex, xValue, aArraySegundo[ aDetalhes:__EnumIndex, xValue:__EnumIndex ]
      NEXT
   ENDIF
NEXT
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder