1

言語: vb.net ファイル サイズ: 1GB など。

テキスト ファイルのエンコーディング: UTF8 (したがって、各文字は異なるバイト数で表されます)。

照合: UnicodeCI (複数の文字が本質的に同じである場合、最も人気のあるバージョンが一意になります。) 私は彼の扱い方を知っていると思います。

各文字は異なるバイト数で表され、各行の文字数も異なるため、各行のバイト数も異なります。

各行のハッシュを計算する必要があると思います。また、行ごとにバッファーの場所を保存する必要があります。次に、バッファを比較する必要があります。次に、同じ行が表示されるかどうかを確認します。

それに最適な特別な機能はありますか?

4

2 に答える 2

1

行の長さによっては、各行の MD5 ハッシュ値を計算して、次の形式で保存できる場合がありますHashMap

Using sr As New StreamReader("myFile")
    Dim lines As New HashSet(Of String)
    Dim md5 As New Security.Cryptography.MD5Cng()

    While sr.BaseStream.Position < sr.BaseStream.Length
        Dim l As String = sr.ReadLine()
        Dim hash As String = String.Join(String.Empty, md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(l)).Select(Function(x) x.ToString("x2")))

        If lines.Contains(hash) Then
            'Lines are not unique
            Exit While
        Else
            lines.Add(hash)
        End If
    End While
End Using

テストされていませんが、これはニーズに対して十分に高速である可能性があります。簡潔さの類似性を維持している、これよりはるかに高速なものは考えられません :)

于 2012-04-04T04:37:30.607 に答える
0

これが現代の答えです

Public Sub makeUniqueForLargeFiles(ByVal strFileSource As String)
    Using sr As New System.IO.StreamReader(strFileSource)
        Dim changeFileName = reserveFileName(strFileSource, False, True)
        Using sw As New System.IO.StreamWriter(reserveFileName(strFileSource, False, True), False, defaultEncoding)
            sr.Peek()
            Dim lines As New Generic.Dictionary(Of Integer, System.Collections.Generic.List(Of Long))
            While sr.BaseStream.Position < sr.BaseStream.Length
                Dim offset = sr.BaseStream.Position
                Dim l As String = sr.ReadLine()
                Dim nextOffset = sr.BaseStream.Position
                Dim hash = l.GetHashCode
                Do ' a trick to put the for each in a "nest" that we can exit from
                    If lines.ContainsKey(hash) Then
                        Using sr2 = New System.IO.StreamReader(strFileSource)
                            For Each offset1 In lines.Item(hash)
                                sr2.BaseStream.Position = offset1
                                Dim l2 = sr2.ReadLine
                                If l = l2 Then
                                    Exit Do 'will sr2.dispose be called here?
                                End If
                            Next
                        End Using
                    Else
                        lines.Add(hash, New Generic.List(Of Long))
                    End If
                    lines.Item(hash).Add(offset)
                    sw.WriteLine(l)
                Loop While False
                sr.BaseStream.Position = nextOffset
            End While
        End Using
    End Using
End Sub
于 2012-04-04T05:58:44.453 に答える