基本情報技術者試験H25秋期午後問8-2（疑似言語）VBAプログラム

```
Sub main()
    Dim Plaindata() As String
    Dim Plength As Integer, Compresseddata(20) As String, Clength As Integer
    Dim Str As String
'    Str = "ABCDEFABCDABCDEF"
    Str = "ABCDEFGABCDEABCDFEFGABCD"
    ReDim Plaindata(0 To Len(Str) - 1)
    For i = 1 To UBound(Plaindata) + 1
        Plaindata(i - 1) = Mid(Str, i, 1)
'       Debug.Print "Plaindata("; i - 1; ")="; Plaindata(i - 1)
    Next i
    Plength = Len(Str)
    
    Call Compress(Plaindata, Plength, Compresseddata, Clength)

    For i = 1 To UBound(Compresseddata)
        Debug.Print Compresseddata(i - 1)
    Next i
    Debug.Print "#####################"
    Call Decompress(Compresseddata, Clength, Plaindata, Plength)
    
    For i = 1 To UBound(Plaindata) + 1
        Debug.Print Plaindata(i - 1)
    Next i
    
End Sub

Sub Compress(ByRef Plaindata() As String, ByRef Plength As Integer, ByRef Compresseddata() As String, ByRef Clength As Integer)
    Dim Esym As String
    Dim Pindex As Integer, Cindex As Integer
    Dim Maxfitnum As Integer, Maxdistance As Integer, Distance As Integer, Fitnum As Integer
    Dim ABCD As String
    ABCD = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    If Plength >= 1 Then
        Esym = "$"
        Pindex = 0
        Cindex = 0
        Do While (Pindex < Plength) And (Pindex < 4)
            Compresseddata(Cindex) = Plaindata(Pindex)
            Debug.Print "Pindex="; Pindex, "Plaindata()="; Plaindata(Pindex), "cindex="; Cindex, "Compresseddata()="; Compresseddata(Cindex)
            Cindex = Cindex + 1
            Pindex = Pindex + 1
        Loop
        
        Do While (Pindex < Plength)
            Maxfitnum = -1
            Maxdistance = -1
            Distance = 4
            Do While ((Distance <= 26) And (Pindex - Distance >= 0))
                Fitnum = 0
                Do While ((Fitnum < Distance) And ((Pindex + Fitnum) < Plength))
                    If Plaindata(Pindex + Fitnum) <> Plaindata(Pindex + Fitnum - Distance) Then
                        Debug.Print "Pindex="; Pindex, "Fitnum="; Fitnum, "Plaindata()="; Plaindata(Pindex + Fitnum), "Distance="; Distance, ";Plaindata()="; Plaindata(Pindex + Fitnum - Distance)
                        Exit Do
                    End If
                    Debug.Print "Pindex="; Pindex, "Fitnum="; Fitnum, "Plaindata()="; Plaindata(Pindex + Fitnum), "Distance="; Distance, "Plaindata()="; Plaindata(Pindex + Fitnum - Distance)
                    Fitnum = Fitnum + 1
                Loop
                
                If (Fitnum >= 4) And (Maxfitnum < Fitnum) Then
                    Maxfitnum = Fitnum
                    Maxdistance = Distance
                    Debug.Print "Maxfitnum="; Maxfitnum, "Maxdistance="; Maxdistance
                End If
                
                Distance = Distance + 1
            Loop
            If Maxfitnum = -1 Then
                Compresseddata(Cindex) = Plaindata(Pindex)
                Debug.Print "Pindex="; Pindex, "Plaindata()="; Plaindata(Pindex), "cindex="; Cindex, "Compresseddata()="; Compresseddata(Cindex)
                Cindex = Cindex + 1
                Pindex = Pindex + 1
            Else
                Compresseddata(Cindex) = Esym
                Compresseddata(Cindex + 1) = Mid(ABCD, Maxdistance, 1)
                Compresseddata(Cindex + 2) = Mid(ABCD, Maxfitnum, 1)
                Debug.Print "Pindex="; Pindex, "Plaindata()="; Plaindata(Pindex), "cindex="; Cindex, "Compresseddata()="; Compresseddata(Cindex); Compresseddata(Cindex + 1); Compresseddata(Cindex + 2)
                Cindex = Cindex + 3
                Pindex = Pindex + Maxfitnum
            End If
        Loop
        Clength = Cindex
    End If
End Sub

Sub Decompress(ByRef Compresseddata() As String, ByVal Clength As Integer, ByRef Plaindata() As String, ByVal Plength As Integer)
    Dim Esym As String
    Dim Pindex As Integer, Cindex As Integer
    Dim Num, Fitcnt, Start As Integer
    If Clength >= 1 Then
        Esym = "$"
        Cindex = 0
        Pindex = 0
        Do While Cindex < Clength
            Debug.Print "Compresseddata("; Cindex; ")="; Compresseddata(Cindex)
            If Compresseddata(Cindex) <> Esym Then
                Plaindata(Pindex) = Compresseddata(Cindex)
                Debug.Print "@Plaindata("; Pindex; ")="; Plaindata(Pindex)
                Pindex = Pindex + 1
                Cindex = Cindex + 1
            Else
                Num = AlphabetToInt(Compresseddata(Cindex + 2))
                Start = AlphabetToInt(Compresseddata(Cindex + 1))
                Debug.Print "Num="; Num, "Start="; Start
                For Fitcnt = 0 To Num - 1
                    Plaindata(Pindex + Fitcnt) = Plaindata(Pindex - Start + Fitcnt)
                    Debug.Print "Plaindata("; Pindex + Fitcnt; ")="; Plaindata(Pindex + Fitcnt)
                Next
                Pindex = Pindex + Num
                Cindex = Cindex + 3
            End If
        Loop
        Plength = Pindex
    End If
End Sub
Function AlphabetToInt(moji As String) As Integer
    Dim i As Integer
    Dim ABCD As String
    ABCD = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    For i = 1 To 26
        If moji = Mid(ABCD, i, 1) Then
            AlphabetToInt = i
            Exit For
        End If
    Next
End Function
```
実行結果：

```
Pindex= 0     Plaindata()=A cindex= 0     Compresseddata()=A
Pindex= 1     Plaindata()=B cindex= 1     Compresseddata()=B
Pindex= 2     Plaindata()=C cindex= 2     Compresseddata()=C
Pindex= 3     Plaindata()=D cindex= 3     Compresseddata()=D
Pindex= 4     Fitnum= 0     Plaindata()=E Distance= 4   ;Plaindata()=A
Pindex= 4     Plaindata()=E cindex= 4     Compresseddata()=E
Pindex= 5     Fitnum= 0     Plaindata()=F Distance= 4   ;Plaindata()=B
Pindex= 5     Fitnum= 0     Plaindata()=F Distance= 5   ;Plaindata()=A
Pindex= 5     Plaindata()=F cindex= 5     Compresseddata()=F
Pindex= 6     Fitnum= 0     Plaindata()=G Distance= 4   ;Plaindata()=C
Pindex= 6     Fitnum= 0     Plaindata()=G Distance= 5   ;Plaindata()=B
Pindex= 6     Fitnum= 0     Plaindata()=G Distance= 6   ;Plaindata()=A
Pindex= 6     Plaindata()=G cindex= 6     Compresseddata()=G
Pindex= 7     Fitnum= 0     Plaindata()=A Distance= 4   ;Plaindata()=D
Pindex= 7     Fitnum= 0     Plaindata()=A Distance= 5   ;Plaindata()=C
Pindex= 7     Fitnum= 0     Plaindata()=A Distance= 6   ;Plaindata()=B
Pindex= 7     Fitnum= 0     Plaindata()=A Distance= 7   Plaindata()=A
Pindex= 7     Fitnum= 1     Plaindata()=B Distance= 7   Plaindata()=B
Pindex= 7     Fitnum= 2     Plaindata()=C Distance= 7   Plaindata()=C
Pindex= 7     Fitnum= 3     Plaindata()=D Distance= 7   Plaindata()=D
Pindex= 7     Fitnum= 4     Plaindata()=E Distance= 7   Plaindata()=E
Pindex= 7     Fitnum= 5     Plaindata()=A Distance= 7   ;Plaindata()=F
Maxfitnum= 5  Maxdistance= 7 
Pindex= 7     Plaindata()=A cindex= 7     Compresseddata()=$GE
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 4   ;Plaindata()=B
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 5   Plaindata()=A
Pindex= 12    Fitnum= 1     Plaindata()=B Distance= 5   Plaindata()=B
Pindex= 12    Fitnum= 2     Plaindata()=C Distance= 5   Plaindata()=C
Pindex= 12    Fitnum= 3     Plaindata()=D Distance= 5   Plaindata()=D
Pindex= 12    Fitnum= 4     Plaindata()=F Distance= 5   ;Plaindata()=E
Maxfitnum= 4  Maxdistance= 5 
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 6   ;Plaindata()=G
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 7   ;Plaindata()=F
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 8   ;Plaindata()=E
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 9   ;Plaindata()=D
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 10  ;Plaindata()=C
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 11  ;Plaindata()=B
Pindex= 12    Fitnum= 0     Plaindata()=A Distance= 12  Plaindata()=A
Pindex= 12    Fitnum= 1     Plaindata()=B Distance= 12  Plaindata()=B
Pindex= 12    Fitnum= 2     Plaindata()=C Distance= 12  Plaindata()=C
Pindex= 12    Fitnum= 3     Plaindata()=D Distance= 12  Plaindata()=D
Pindex= 12    Fitnum= 4     Plaindata()=F Distance= 12  ;Plaindata()=E
Pindex= 12    Plaindata()=A cindex= 10    Compresseddata()=$ED
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 4   ;Plaindata()=A
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 5   ;Plaindata()=E
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 6   ;Plaindata()=D
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 7   ;Plaindata()=C
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 8   ;Plaindata()=B
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 9   ;Plaindata()=A
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 10  ;Plaindata()=G
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 11  Plaindata()=F
Pindex= 16    Fitnum= 1     Plaindata()=E Distance= 11  ;Plaindata()=G
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 12  ;Plaindata()=E
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 13  ;Plaindata()=D
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 14  ;Plaindata()=C
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 15  ;Plaindata()=B
Pindex= 16    Fitnum= 0     Plaindata()=F Distance= 16  ;Plaindata()=A
Pindex= 16    Plaindata()=F cindex= 13    Compresseddata()=F
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 4   ;Plaindata()=B
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 5   ;Plaindata()=A
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 6   Plaindata()=E
Pindex= 17    Fitnum= 1     Plaindata()=F Distance= 6   ;Plaindata()=A
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 7   ;Plaindata()=D
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 8   ;Plaindata()=C
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 9   ;Plaindata()=B
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 10  ;Plaindata()=A
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 11  ;Plaindata()=G
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 12  ;Plaindata()=F
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 13  Plaindata()=E
Pindex= 17    Fitnum= 1     Plaindata()=F Distance= 13  Plaindata()=F
Pindex= 17    Fitnum= 2     Plaindata()=G Distance= 13  Plaindata()=G
Pindex= 17    Fitnum= 3     Plaindata()=A Distance= 13  Plaindata()=A
Pindex= 17    Fitnum= 4     Plaindata()=B Distance= 13  Plaindata()=B
Pindex= 17    Fitnum= 5     Plaindata()=C Distance= 13  Plaindata()=C
Pindex= 17    Fitnum= 6     Plaindata()=D Distance= 13  Plaindata()=D
Maxfitnum= 7  Maxdistance= 13 
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 14  ;Plaindata()=D
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 15  ;Plaindata()=C
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 16  ;Plaindata()=B
Pindex= 17    Fitnum= 0     Plaindata()=E Distance= 17  ;Plaindata()=A
Pindex= 17    Plaindata()=E cindex= 14    Compresseddata()=$MG
A
B
C
D
E
F
G
$
G
E
$
E
D
F
$
M
G



#####################
Compresseddata( 0 )=A
@Plaindata( 0 )=A
Compresseddata( 1 )=B
@Plaindata( 1 )=B
Compresseddata( 2 )=C
@Plaindata( 2 )=C
Compresseddata( 3 )=D
@Plaindata( 3 )=D
Compresseddata( 4 )=E
@Plaindata( 4 )=E
Compresseddata( 5 )=F
@Plaindata( 5 )=F
Compresseddata( 6 )=G
@Plaindata( 6 )=G
Compresseddata( 7 )=$
Num= 5        Start= 7 
Plaindata( 7 )=A
Plaindata( 8 )=B
Plaindata( 9 )=C
Plaindata( 10 )=D
Plaindata( 11 )=E
Compresseddata( 10 )=$
Num= 4        Start= 5 
Plaindata( 12 )=A
Plaindata( 13 )=B
Plaindata( 14 )=C
Plaindata( 15 )=D
Compresseddata( 13 )=F
@Plaindata( 16 )=F
Compresseddata( 14 )=$
Num= 7        Start= 13 
Plaindata( 17 )=E
Plaindata( 18 )=F
Plaindata( 19 )=G
Plaindata( 20 )=A
Plaindata( 21 )=B
Plaindata( 22 )=C
Plaindata( 23 )=D
A
B
C
D
E
F
G
A
B
C
D
E
A
B
C
D
F
E
F
G
A
B
C
D
```