Página 1 de 1

Comparar matrizes

Enviado: 13 Dez 2019 00:05
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.

Comparar matrizes

Enviado: 13 Dez 2019 08:30
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

Comparar matrizes

Enviado: 13 Dez 2019 09:12
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?

Comparar matrizes

Enviado: 13 Dez 2019 09:22
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.

Comparar matrizes

Enviado: 13 Dez 2019 10:03
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.

Comparar matrizes

Enviado: 13 Dez 2019 10:15
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.

Comparar matrizes

Enviado: 13 Dez 2019 13:20
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

Comparar matrizes

Enviado: 13 Dez 2019 14:23
por elaineosm
vou testar aqui.
Mt Obg Ranier e J.Quintas

Comparar matrizes

Enviado: 13 Dez 2019 14:39
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