USUÁRIO:      SENHA:        SALVAR LOGIN ?    Adicione o VBWEB na sua lista de favoritos   Fale conosco 

 

  Fórum

  Visual Basic
Voltar
Autor Assunto:  Algortmo de Huffman
Douglas
não registrado
ENUNCIADA !
Postada em 11/01/2012 11:35 hs   
Caros Colegas, já estou a 2 dias tentando fazer uma rotina funcionar baseado no Algortimo de Huffman, criado pelo Frederick conforme no link abaixo, que tem o exemplo.

Funciona perfeitamente caregando um arquivo de texto, no entanto não consigo fazer o mesmo passando uma variavel  string diretamente para a função:
Public Function EncodeString(Text As String) As String

Por favor peço  que alguém me ajude a desvendar este algortimo e porque fuciona lendo os bytes de arquivo de texto, mas não funciona com uma string, mesmo já tento a função pronta para esta finalidade?

O que eu preciso é informar a a string.


Dim strTEXT As String

Me.Text1 = Huffman.EncodeString(strTEXT)

Deveria me retornar na caixa de texto Text1, da mesma forma que gera o arquivo de texto.


http://www.visualbasiccode.net/vb/scripts/ShowCode.asp?txtCodeId=11000&lngWId=-1
   
Treze
Pontos: 2843 Pontos: 2843
SÃO VICENTE
SP - BRASIL
ENUNCIADA !
Postada em 11/01/2012 12:04 hs            
mas vc não vai conseguir mesmo o algoritimo foi desenvolvido para compactar arquivos, e não uma sequencia de texto, não sei nem porque compactar uma string.

   
Douglas
não registrado
Postada em 11/01/2012 12:19 hs   
Treze, não creio que seja isto, pois a intenção do Algoritimo é justamente compactar a string e não arquivos. o algoritmo faz uma varredura na string para buscar as probabilidades de repetições, assim a string vai ficando menor. Eu preciso de encurtar o tamanho de uma string e por isso existe N formas como Aritmeticas, RLE, Huffman e etc...

No exemplo acima funciona exatamente assim, você tem uma string de menor comprimento no final.
Apenas não consigo adaptar para uma string, mesmo carregando o Array de bytes.
     
Thiago
não registrado
Postada em 18/01/2012 12:51 hs   
Exato, se você abrir o binário de um arquivo vai encontrar várias strings lá.

Quanto a seu problema, não li a codificação que você postou, mas acredito que ele esteja tentando ler o arquivo como binary, por isso você não consegue utilizar a string.

É diferente passar uma parâmetro binary de um parâmetro string.
Acredito que no exemplo que você postou o programador tenha como objetivo utilizar o Huffman em arquivos, enquanto você tem como objetivo utilizar em String's. Nesse caso, será necessário realizar modificações no aplicativo para atender a suas necessidades.
     
Douglas
não registrado
ENUNCIADA !
Postada em 19/01/2012 08:19 hs   
Obrigado pelo Retorno!

Na verdade o algoritmo não usa binário. Ele guarda em um array de Bytes e depois armazena no CopyMem. Eu até já consegui pegando o valor do byte no CopyMem e montei a string se usar o arquivo. Mas agora quando tento reverter o processo, da o erro de Out of memory. Nâo sei como que ele o cálculo inverso, mas as string parece que entrou um um loop continuo e de 1120 caracteres foi para 50 milhões.

Vou postar aqui o parte do Codigo:
Veja que ByteArray já foi armazenado todos os bytes de uma string.

dessa forma:
  Dim ByteArray() As Byte

  'Convert the string to a byte array
  ByteArray() = StrConv(Text, vbFromUnicode)
  
'Compress the data
' Call EncodeByte(ByteArray(), UBound(ByteArray) + 1)
  

  
  'Compress the byte array
  Call EncodeByte(ByteArray, Len(Text))

Aqui a funnção que vai decodificar as string e o erro aconteçe no ResultLen que fica com valor monstruoso. Fazendo a leitura em um arquivo de texto isso não acontece.





Public Sub DecodeByte(ByteArray() As Byte, ByteLen As Long)
  'On Error Resume Next
  Dim i As Long
  Dim j As Long
  Dim Pos As Long
  Dim Char As Byte
  Dim CurrPos As Long
  Dim Count As Integer
  Dim CheckSum As Byte
  Dim Result() As Byte
  Dim BitPos As Integer
  Dim NodeIndex As Long
  Dim ByteValue As Byte
  Dim ResultLen As Long
  Dim NodesCount As Long
  Dim lResultLen As Long
  Dim NewProgress As Integer
  Dim CurrProgress As Integer
  Dim BitValue(0 To 7) As Byte
  Dim Nodes(0 To 511) As HUFFMANTREE
  Dim CharValue(0 To 255) As ByteArray
  
  If (ByteArray(0) <> 72) Or (ByteArray(1) <> 69) Or (ByteArray(3) <> 13) Then
    'The source did not contain the identification
    'string "HE?" & vbCr where ? is undefined at
    'the moment (does not matter)
  ElseIf (ByteArray(2) = 48) Then
    'The text is uncompressed, return the substring
    'Decode = Mid$(Text, 5)
    Call CopyMem(ByteArray(0), ByteArray(4), ByteLen - 4)
    ReDim Preserve ByteArray(0 To ByteLen - 5)
    Exit Sub
  ElseIf (ByteArray(2) <> 51) Then
    'This is not a Huffman encoded string
    Err.Raise vbObjectError, "HuffmanDecode()", "The data either was not compressed with HE3 or is corrupt (identification string not found)"
    Exit Sub
  End If
  
  CurrPos = 5
    
  'Extract the checksum
  CheckSum = ByteArray(CurrPos - 1)
  CurrPos = CurrPos + 1
  
  'Extract the length of the original string
  Call CopyMem(ResultLen, ByteArray(CurrPos - 1), 4)
  CurrPos = CurrPos + 4
  lResultLen = ResultLen
  
  'If the compressed string is empty we can
  'skip the function right here
  If (ResultLen = 0) Then Exit Sub
    'MsgBox ResultLen, vbInformation, ByteArray()

  'Create the result array
  ReDim Result(0 To ResultLen - 1)
  'Get the number of characters used
  Call CopyMem(Count, ByteArray(CurrPos - 1), 2)
  CurrPos = CurrPos + 2
  
  'Get the used characters and their
  'respective bit sequence lengths
  For i = 1 To Count
    With CharValue(ByteArray(CurrPos - 1))
      CurrPos = CurrPos + 1
      .Count = ByteArray(CurrPos - 1)
      CurrPos = CurrPos + 1
      ReDim .Data(0 To .Count - 1)
    End With
  Next
  
  'Create a small array to hold the bit values,
  'this is (still) faster than calculating on-fly
  For i = 0 To 7
    BitValue(i) = 2 ^ i
  Next
  
  'Extract the Huffman Tree, converting the
  'byte sequence to bit sequences
  ByteValue = ByteArray(CurrPos - 1)
  CurrPos = CurrPos + 1
  BitPos = 0
  For i = 0 To 255
    With CharValue(i)
      If (.Count > 0) Then
        For j = 0 To (.Count - 1)
          If (ByteValue And BitValue(BitPos)) Then .Data(j) = 1
          BitPos = BitPos + 1
          If (BitPos = 8) Then
            ByteValue = ByteArray(CurrPos - 1)
            CurrPos = CurrPos + 1
            BitPos = 0
          End If
        Next
      End If
    End With
  Next
  If (BitPos = 0) Then CurrPos = CurrPos - 1
  
  'Create the Huffman Tree
  NodesCount = 1
  Nodes(0).LeftNode = -1
  Nodes(0).RightNode = -1
  Nodes(0).ParentNode = -1
  Nodes(0).Value = -1
  For i = 0 To 255
    Call CreateTree(Nodes(), NodesCount, i, CharValue(i))
  Next
  
  'Decode the actual data
  ResultLen = 0
  For CurrPos = CurrPos To ByteLen
    ByteValue = ByteArray(CurrPos - 1)
    For BitPos = 0 To 7
      If (ByteValue And BitValue(BitPos)) Then
        NodeIndex = Nodes(NodeIndex).RightNode
      Else
        NodeIndex = Nodes(NodeIndex).LeftNode
      End If
      If (Nodes(NodeIndex).Value > -1) Then
        Result(ResultLen) = Nodes(NodeIndex).Value
        ResultLen = ResultLen + 1
        If (ResultLen = lResultLen) Then GoTo DecodeFinished
        NodeIndex = 0
      End If
    Next
    If (CurrPos Mod 10000 = 0) Then
      NewProgress = CurrPos / ByteLen * PROGRESS_DECODING
      If (NewProgress <> CurrProgress) Then
        CurrProgress = NewProgress
        RaiseEvent Progress(CurrProgress)
      End If
    End If
  Next
DecodeFinished:

  'Verify data to check for corruption.
  Char = 0
  For i = 0 To (ResultLen - 1)
    Char = Char Xor Result(i)
    If (i Mod 10000 = 0) Then
      NewProgress = i / ResultLen * PROGRESS_CHECKCRC + PROGRESS_DECODING
      If (NewProgress <> CurrProgress) Then
        CurrProgress = NewProgress
        RaiseEvent Progress(CurrProgress)
      End If
    End If
  Next
  If (Char <> CheckSum) Then
    Err.Raise vbObjectError, "clsHuffman.Decode()", "The data might be corrupted (checksum did not match expected value)"
  End If

  'Return the uncompressed string
  ReDim ByteArray(0 To ResultLen - 1)
  Call CopyMem(ByteArray(0), Result(0), ResultLen)
  
  'Make sure we get a "100%" progress message
  If (CurrProgress <> 100) Then
    RaiseEvent Progress(100)
  End If
  
End Sub

   
Douglas
não registrado
Postada em 20/01/2012 13:45 hs   
Parece que desta vez me deparei um grande problema. Dificil ainda achar um bom programador que entenda bem de algoritmos no Brasil. Pesquisando na NET, Codificação Aritmética, Huffaman, RLE, Gzip entre tantos outros algortimos de compressão de strings tem origens estrangeiras, ninguém no Brasil e nenhum site aqui fala deste assunto.

Caso alguém tenha algum endereço ou algum algoritmo, ou mesmo esteja ainda estudando na faculdade, pergunte ao seu professor e quem sabe mesmo sendo de outra linguagem eu consiga fazer a tradução para o VB6. No .NET isso já vem pronto usando o Gzip.
     
Página(s): 1/1    


Seu Nome:

Seu eMail:

ALTERAR PARA MODO HTML
Mensagem:

[:)] = 
[:P] = 
[:(] = 
[;)] = 

HTML DESLIGADO

     
 VOLTAR

  



CyberWEB Network Ltda.    © Copyright 2000-2025   -   Todos os direitos reservados.
Powered by HostingZone - A melhor hospedagem para seu site
Topo da página