Página 1 de 1
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 01 Jul 2021 13:42
por informais
Olá amigos, tudo bem
Preciso ler uma (string/Texto) que na verdade está armazenando dezenas, e que está separada por PIPE
Preciso saber quantas vezes e quais números repetem nela, separados por PIPE |
Exemplo veja a String/texto
04|09|16|23|39|43|80|85|94|99 nenhuma dezena se repete
30|30|30|30|30|01|01|01|01|01 Já nessa o 30 e 01 Repete várias vezes
04|04|16|23|39|43|80|85|94|99 04 - 2 Vezes
etc..
Preciso ter um retorno de qual(ais)dezena se Repetem
Exemplo a primeira seria assim Não tem Repetidos
Espero que tenham entendido
Essa informação está dentro de uma tabela campo Char, cada um em uma linha da tabela
Assim que fica no banco de dados
17|20|22|27|30|35|41|42|75|95
71|16|25|34|70|27|80|43|61|06
04|12|17|29|39|43|48|67|69|81
95|94|98|97|08|77|83|84|85|20
01|01|01|01|01|01|01|01|01|01
04|06|08|12|17|28|29|39|79|86
11|18|23|27|39|43|49|74|77|84
27|95|06|35|61|56|98|49|17|01
43|16|74|56|84|08|34|55|69|06
01|06|09|16|35|49|62|70|89|99
18|17|38|98|06|02|43|22|49|27
27|06|32|35|75|81|08|29|52|56
06|18|23|35|38|60|71|89|95|98
09|27|23|02|95|12|78|41|60|77
04|17|20|38|42|56|61|79|83|95
67|42|02|56|77|98|24|52|86|61
11|01|18|22|34|42|56|66|75|92
69|69|69|69|69|69|69|69|69|69
82|52|08|18|11|67|84|66|70|80
11|69|38|23|28|62|66|08|77|21
01|01|01|01|01|01|01|01|01|01
08|11|12|20|21|55|69|70|80|96
16|16|16|16|16|16|16|16|16|16
16|16|16|16|16|16|16|16|16|16
17|21|32|39|48|63|70|79|55|84
32|21|48|15|99|22|83|35|97|25
11|16|18|30|34|93|94|71|70|69
01|04|09|17|27|36|43|81|83|97
49|56|20|52|62|63|74|70|40|66
11|96|32|22|21|84|35|06|62|18
09|98|11|35|85|29|75|52|32|30
25|28|35|60|61|11|11|12|16|78
02|08|15|22|29|42|55|69|82|89
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 01 Jul 2021 17:57
por JoséQuintas
Em Clipper mesmo?
Se os números sempre estão com dois caracteres, um FOR/NEXT poderia ser usado.
Código: Selecionar todos
FOR nCont = 1 TO Len( cText ) STEP 3
nNumero := Val( Substr( cText, nCont, 2 ) )
NEXT
Talvez um array pra armazenar os números e a quantidade de cada um, se a quantidade for importante.
Código: Selecionar todos
aList := {}
...
nPos := ASCan( aList, { | e | e[ 1 ] == nNumero } ) // a confirmar se no ASCan() do Clipper o parâmetro do codeblock é o primeiro
IF nPos == 0
AAdd( aList, { nNumero, 1 } )
ELSE
aList[ nPos, 2 ] += 1
ENDIF
Depois seria listar as quantidades maiores que 1
Código: Selecionar todos
FOR nCont = 1 TO Len( aList )
IF aList[ nCont, 2 ] > 1
? "numero:", aList[ nCont, 1 ], "qtde:", aList[ nCont, 2 ]
ENDIF
NEXT
Seria por aí, depende exatamente de como precisa do resultado.
Se fosse Harbour, poderia usar o hb_RegExSplit() pra separar os números mais rápido, e também o FOR/EACH, ou talvez AEval().
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 01 Jul 2021 18:58
por ANDRIL
Veja se é isso que procura, creio que deva compilar normalmente em Clipper.
Código: Selecionar todos
txt = "04|09|16|23|39|43|80|85|94|99|30|30|30|30|30|01|01|01|01|01|04|04|16|23|39|43|80|85|94"
aNum = Split(txt)
aSort(aNum)
maximo=len(aNum)
aSaida:={}
for i=1 to maximo
pos=ascan(aSaida,{|e| e[1]=aNum[i]})
if pos=0
aadd(aSaida,{aNum[i],1})
else
aSaida[pos][2]+=1
endif
next
for i=1 to len(aSaida)
? aSaida[i][1], aSaida[i][2]
next
wait"veja o resultado"
*******************
Function Split(txt)
*******************
//txt = "04|09|16|23|39|43|80|85|94|99|30|30|30|30|30|01|01|01|01|01|04|04|16|23|39|43|80|85|94"
txt = iif(!"|"$txt,txt+"|",txt)
aNum:={}
do while len(txt)>0
pos=AT("|",txt)
if pos>0
num=substr(txt,1,AT("|",txt)-1)
else
num=txt
txt=""
endif
aadd(aNum,num)
if !"|"$txt
exit
endif
pos=AT("|",txt)
txt=substr(txt,AT("|",txt)+1)
enddo
return aNum
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 02 Jul 2021 11:05
por informais
Olá amigo ANDRIL
A principio exatamente o que quero, agora é Adptar a minha realidade
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 02 Jul 2021 14:10
por JoséQuintas
A função Split ficou meio confusa.
Talvez melhor assim:
Código: Selecionar todos
FUNCTION Split( cTxt )
LOCAL aList := {}
cTxt := Trim( cTxt )
IF Right( cTxt, 1 ) != "|" .AND. Len( cTxt ) > 1
cTxt += "|"
ENDIF
DO WHILE "|" $ cTxt
nPos := At( "|", cTxt )
cNum := Substr( cTxt, 1, nPos - 1 )
cTxt := Substr( cTxt, nPos + 1 )
AAdd( aList, cNum )
ENDDO
RETURN aList
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 03 Jul 2021 01:38
por alxsts
Olá!
Segue a minha versão da rotina:

Código: Selecionar todos
// Preciso ler uma (string/Texto) que na verdade está armazenando dezenas,
// e que está separada por PIPE
// Preciso saber quantas vezes e quais números repetem nela, separados por PIPE |
#include "setcurs.ch"
PROCEDURE Duplicados()
// Alexandre Santos - Fórum PC Toledo
LOCAL cDup, cString, nLimit, nOuter, cSearch
LOCAL nCount, nInner, nOffSet, cOldColor, nOldCursor
RELEASE GetList
REQUEST DBFCDX
RDDSETDEFAULT( "DBFCDX" )
cOldColor := SetColor( "W+/B,B/W" ) ; CLS
nOldCursor := SC_NONE
If ! File( "DEZENAS.DBF" )
DbCreate("Dezenas", { { "Dezenas", "C", 29, 0 }, { "Duplicados", "C", 80, 0 } }, "DBFCDX" )
DBUSEAREA( .T., "DBFCDX", "DEZENAS", "DEZENAS", .F. )
DbAppend() ; DEZENAS->dezenas := "17|20|22|27|30|35|41|42|75|95"
DbAppend() ; DEZENAS->dezenas := "71|16|25|34|70|27|80|43|61|06"
DbAppend() ; DEZENAS->dezenas := "04|12|17|29|39|43|48|67|69|81"
DbAppend() ; DEZENAS->dezenas := "95|94|98|97|08|77|83|84|85|20"
DbAppend() ; DEZENAS->dezenas := "01|01|01|01|01|01|01|01|01|01"
DbAppend() ; DEZENAS->dezenas := "04|06|08|12|17|28|29|39|79|86"
DbAppend() ; DEZENAS->dezenas := "11|18|23|27|39|43|49|74|77|84"
DbAppend() ; DEZENAS->dezenas := "27|95|06|35|61|56|98|49|17|01"
DbAppend() ; DEZENAS->dezenas := "43|16|74|56|84|08|34|55|69|06"
DbAppend() ; DEZENAS->dezenas := "01|06|09|16|35|49|62|70|89|99"
DbAppend() ; DEZENAS->dezenas := "18|17|38|98|06|02|43|22|49|27"
DbAppend() ; DEZENAS->dezenas := "27|06|32|35|75|81|08|29|52|56"
DbAppend() ; DEZENAS->dezenas := "06|18|23|35|38|60|71|89|95|98"
DbAppend() ; DEZENAS->dezenas := "09|27|23|02|95|12|78|41|60|77"
DbAppend() ; DEZENAS->dezenas := "04|17|20|38|42|56|61|79|83|95"
DbAppend() ; DEZENAS->dezenas := "67|42|02|56|77|98|24|52|86|61"
DbAppend() ; DEZENAS->dezenas := "11|01|18|22|34|42|56|66|75|92"
DbAppend() ; DEZENAS->dezenas := "69|69|69|69|69|69|69|69|69|69"
DbAppend() ; DEZENAS->dezenas := "82|52|08|18|11|67|84|66|70|80"
DbAppend() ; DEZENAS->dezenas := "11|69|38|23|28|62|66|08|77|21"
DbAppend() ; DEZENAS->dezenas := "01|01|01|01|01|01|01|01|01|01"
DbAppend() ; DEZENAS->dezenas := "08|11|12|20|21|55|69|70|80|96"
DbAppend() ; DEZENAS->dezenas := "16|16|16|16|16|16|16|16|16|16"
DbAppend() ; DEZENAS->dezenas := "16|16|16|16|16|16|16|16|16|16"
DbAppend() ; DEZENAS->dezenas := "17|21|32|39|48|63|70|79|55|84"
DbAppend() ; DEZENAS->dezenas := "32|21|48|15|99|22|83|35|97|25"
DbAppend() ; DEZENAS->dezenas := "11|16|18|30|34|93|94|71|70|69"
DbAppend() ; DEZENAS->dezenas := "01|04|09|17|27|36|43|81|83|97"
DbAppend() ; DEZENAS->dezenas := "49|56|20|52|62|63|74|70|40|66"
DbAppend() ; DEZENAS->dezenas := "11|96|32|22|21|84|35|06|62|18"
DbAppend() ; DEZENAS->dezenas := "09|98|11|35|85|29|75|52|32|30"
DbAppend() ; DEZENAS->dezenas := "25|28|35|60|61|11|11|12|16|78"
DbAppend() ; DEZENAS->dezenas := "02|08|15|22|29|42|55|69|82|89"
DbAppend() ; DEZENAS->dezenas := "55|08|15|02|29|08|55|15|42|08"
// 0...x....1....x....2....x...2
// 12345678901234567890123456789
Else
DBUSEAREA( .T., "DBFCDX", "DEZENAS", "DEZENAS", .F. )
Endif
DEZENAS->( DbGoTop() )
nOffSet := 3
// percorre os registros
While ! DEZENAS->( Eof() )
cDup := ""
cString := DEZENAS->dezenas
nLimit := Len( cString )
nOuter := 1
// loop externo... percorre as dezenas de cada registro
While nOuter < nLimit
cSearch := SubStr( cString, nOuter, 2 )
nInner := 1
nCount := 0
// loop interno... conta cada dezena nas dezenas do registro atual
While nInner < nLimit
If Substr( cString, nInner, 2 ) == cSearch
nCount++
Endif
nInner += nOffSet
Enddo
// se encontrou mais que um
If nCount > 1
// se é a primeira vez que encontrou, guarda
If At( cSearch + ":", cDup ) == 0
cDup += If( ! Empty( cDup ), ", ", "" ) + cSearch + ":" + LTrim( Str( nCount ) )
Endif
Endif
nOuter += nOffSet
Enddo // nOuter < nLimit
// se encontrou, grava no próprio registro (arquivo aberto em modo exclusivo)
If ! Empty( cDup )
DEZENAS->Duplicados := cDup
Endif
// avança registro
DEZENAS->( DbSkip() )
Enddo // ! DEZENAS->( Eof() )
// exibe registros, fecha arquivo
DEZENAS->( Browse(), DbCloseArea() )
// restaura tela
SetColor( cOldColor ) ; CLS ; SetCursor( nOldCursor )
RETURN
//----------------------------------------------------------------------------------------------------
JoséQuintas escreveu:A função Split ficou meio confusa.
Segue a minha versão:
Código: Selecionar todos
//----------------------------------------------------------------------------------------------------
FUNCTION aTokens( cString, cDelimiter )
// Alexandre Santos - Fórum PC Toledo
LOCAL aTokens := {}, nPos, nLen
If Valtype( cString ) == "C" .And. ( ! Empty( cString := Alltrim( cString ) ) )
If Valtype( cDelimiter ) == "C" .And. ( ! Empty( cDelimiter ) )
While ( nPos := At( cDelimiter, cString ) ) > 0
AAdd( aTokens, SubStr( cString, 1, nPos - 1 ) )
cString := SubStr( cString, nPos + 1 )
Enddo
AAdd( aTokens, cString )
Else
// sem delimitador... retorna byte a byte
nLen := Len( cString )
For nPos := 1 To nLen
AAdd( aTokens, SubStr( cString, nPos, 1 ) )
Next
Endif
Endif
RETURN aTokens
//----------------------------------------------------------------------------------------------------
informais escreveu:Preciso saber quantas vezes e quais números repetem nela, separados por PIPE |
Não ficou claro se o retorno também é uma string com o resultado separado por pipes. Mas isto é fácil de adaptar...
Saber se uma sequencia de Numeros/caracteres, tem repetentes
Enviado: 07 Jul 2021 12:59
por informais
Obrigado a todos,
Fiz um Apanhado das dicas dos amigos e está resolvido