Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring

_Créditos das imagens: ChatGPT_ ### LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring Resolver o problema do [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/description/) é um exercício clássico de programação, que desafia desenvolvedores a encontrar a maior substring palindrômica dentro de uma string. Recentemente, exploramos soluções tanto em Harbour quanto em TLPP (Total Language Protheus Programming). Neste artigo, comparamos as implementações nessas duas linguagens, destacando suas semelhanças, diferenças e funcionalidades específicas. #### Implementações em Harbour ##### Versão 5.1 Essa solução utiliza a técnica de expansão a partir do centro do palíndromo. Cada caractere ou par de caracteres consecutivos é considerado um possível "centro". O algoritmo expande em ambas as direções enquanto os caracteres forem iguais, retornando o maior palíndromo encontrado. ##### Versão 5....

Protheus :: Ponto de Entrada U_F050ALT()

A proposta do "Ponto de Entrada" U_F050ALT(), pela sua descrição, "ser executado após a confirmação da alteração", não é de fato verdadeira. Ele sempre será executado independente de ter ocorrido alteração ou não na função FA050Alter() do programa  FINA050. Isso pode gerar a ocorrência de efeitos colaterais, principalmente se, para a execução do Ponto de" Entrada" " U_F050ALT, a condição seja que alguma informação tenha sido alterada no SE2.

A questão é que a pessoa que implementou a chamada ao "Ponto de Entrada" U_F050ALT não verifica, de fato, se ocorreu alguma alteração, e muito menos o retorno da axAltera.

Para resolver esse problema, tive que abrir mão do uso de um outro "Ponto de Entrada" o FA050UPD (que pode ser executado para a "pré-validação" da Alteração e é chamado antes da axAltera).

Nesse "Ponto de Entrada" vamos ter que salvar em memória o conteúdo do registro a ser alterado e comparar, quando da execução do F050ALT, se de fato alguma alteração foi efetuada.

A implementação ficaria da seguinte forma:

  1. No "Ponto de Entrada" FA050UPD criar uma variável de escopo PUBLIC que conterá um Array com os valores de todos os campos do SE2;
  2. No "Ponto de Entrada" F050ALT recarregar esses valores e comparar com o Array armazenado anteriormente, e, se eles forem iguais, não ocorreu alteração, então não faz nada.
Em Termos de código teríamos algo como:

Programa U_FA050UPD.PRX ("Ponto de Entrada": FA050UPD)

#INCLUDE "PROTHEUS.CH"
/*/
 Funcao:  U_FA050UPD()
 Descricao: Ponto de Entrada da Rotina FINA050 (Chamado Antes da AxAltera)
    Sera utilizado para Armazenar o conteudo Anterior do SE2 para comparacao no Ponto De Entrada F050ALT
    para saber se alguma alteracao, de fato, aconteceu.
    
/*/
User Function FA050UPD()

 Local lFA050UPD  := .T.
 
 PUBLIC __FA050UPD := {}
 
 BEGIN SEQUENCE
    
  __FA050UPD := StaticCall( U_FA050UPD , RegToArray , "SE2" , SE2->( Recno() ) )

 END SEQUENCE

Return( lFA050UPD )

/*/
 Funcao:  RegToArray
 Autor:  Marinaldo de Jesus 
 Data:  17/09/2010
 Descricao: Carregar Valores de um Determinado Registro em Memoria
 Sintaxe: 
/*/
Static Function RegToArray( cAlias , nRecno )

 Local aValues  := {}
 Local adbStruct
 
 Local nField
 Local nFields

 DEFAULT cAlias := Alias()
 DEFAULT nRecno := (cAlias)->( Recno() )

 adbStruct  := (cAlias)->( dbStruct() )

 (cAlias)->( MsGoto( nRecno ) )
 
 nFields := Len( adbStruct )
 aValues := Array( nFields )

 For nField := 1 To nFields
  aValues[ nField ] := (cAlias)->( FieldGet( nField ) )
 Next nField

Return( aValues  )
Programa U_F050ALT.PRX ("Ponto de Entrada": F050ALT)


#INCLUDE "PROTHEUS.CH"
/*/
 Funcao:  U_F050ALT()
 Descricao: Ponto de Entrada da Rotina FINA050
    Se ocorrer alteração no Titulo o Processo de Aprovacao devera ser reiniciado
/*/
User Function F050ALT()

 Local aF050Alt

 BEGIN SEQUENCE

  nSE2Recno  := SE2->( Recno() )

  IF ( Type( "__FA050UPD" ) == "A" )
   aF050Alt := StaticCall( U_FA050UPD , RegToArray , "SE2" , nSE2Recno )
   IF ( ArrayCompare( @__FA050UPD , @aF050Alt ) )
    BREAK
   EndIF
   __FA050UPD := aF050Alt
  EndIF

 END SEQUENCE

Return( NIL )

Ou seja, temos que fazer mágica para contornar um problema que seria muito simples de se resolver se quem implementou o "Ponto de Entrada" F050ALT o tivesse feito da maneira a que se propôs.

[]s
иαldσ dj

Comentários

  1. Boa dica Marinaldo... Realmente isso ocorre de fato mesmo....

    Gostaria de saber o porquê "dos comandos Begin Seguence e End Sequence ???"

    Abraços,

    Fernando

    ResponderExcluir

Postar um comentário

Postagens mais visitadas