2

VS 2010では、文字列の大きなリストがあり、リスト内の各項目には文字列のリストも含まれています(これ以上は進みません)。良いことは、追加のみが行われることです。リストから何も削除されません。

データベースを使いたくない。リストがかなり大きくなる可能性があるため、XMLは私には遅いように見えました。私の場合、一般的な解決策は見つかりませんでした。何か案が?

編集:さて、私のコードのいくつかは私が推測することをより明確にするでしょう。

Class Word
    Public theWord As String
    Public SubWords As New List(Of SubWord)
    Public Count As Integer = 1
    Sub New(ByRef Word As String)
        theWord = Word
    End Sub
    Public Sub AddSubWord(ByRef Word As String)
        Dim SubWordCount As Integer = SubWords.Count - 1
        Dim Found As Boolean
        For i = 0 To SubWordCount
            If SubWords(i).theWord = Word Then
                SubWords(i).Count += 1
                Found = True
                Exit For
            End If
        Next
        If Found = False Then
            SubWords.Add(New SubWord(Word))
        End If
    End Sub
    Public Overrides Function ToString() As String
        Return theWord
    End Function
End Class

Class SubWord
    Public theWord As String
    Public Count As Integer = 1
    Sub New(ByRef Word As String)
        theWord = Word
    End Sub
    Public Overrides Function ToString() As String
        Return theWord
    End Function
End Class

また、私が持っているリストは次のとおりです。

Dim Words As New List(Of Word)

目的は、単語がリストにない場合はリストに単語を追加し、そうでない場合はその単語の数を増やすことです。サブワードについても同じです。後で、すべてのリストがカウントに従ってソートされます。非常に多くの単語があり、それぞれに巨大なサブワードリストがあります。

4

1 に答える 1

1

XMLは最良の選択肢のように思えますが、効率が本当に心配で、データ構造が将来変更されないことが確実な場合は、データを区切りテキストファイルに保存するだけで済みます。例えば:

Private Sub SaveList(filePath As String, list As List(Of List(Of String)))
    Const fieldDelimiter As String = ","
    Const recordDelimiter As String = Environment.NewLine
    Dim temp As New List(Of String)()
    For each i as List(Of String) in list)
        temp.Add(String.Join(fieldDelimiter, i.ToArray()))
    Next
    Dim contents As String = String.Join(recordDelimiter, temp.ToArray())
    File.WriteAllText(filePath, contents)
End Sub

または、より効率的に:

Private Sub SaveList(filePath As String, list As List(Of List(Of String)))
    Const fieldDelimiter As String = ","
    Const recordDelimiter As String = Environment.NewLine
    Using writer As New StreamWriter(filePath)
        Dim firstRecord As Boolean = True
        For Each record as List(Of String) In list)
            If firstRecord Then
                firstRecord = False
            Else
                writer.Write(recordDelimiter)
            End If
            Dim firstField As Boolean = True
            For Each field As String In record
                If firstField Then
                    firstField = False
                Else
                    writer.Write(fieldDelimiter)
                End If
                writer.Write(field)
            Next
        Next
    End Using
End Sub    

このアプローチの欠点は、使用する区切り文字がいずれかのレコードのどのフィールドでも発生しないようにする必要があることです。文字列に特定の異常な文字が含まれないことが確実にわかっている場合は、それを使用できます。それ以外の場合、代替手段は発生を回避することです。したがって、たとえば、区切り文字としてコンマを使用している場合は、のすべての出現箇所をで置き換えてから、のすべての出現箇所をで置き換える必要が,あります。もちろん、これは保存ロジックだけでなく、読み込みロジックも複雑にします。\,\\\

アップデート

速度が主な関心事であり、WordsとSubwordsがすべて100文字未満になることを保証できる場合、データの読み取りと書き込みの最速の方法は、テキストファイルの新しい行に各単語を書き込むことです。固定幅フィールドを使用する各サブワード。たとえば、最大長が5の場合、ファイルは次のようになります。

Word Sub1 Sub2
W2   SW1  SW2  SW3
W3
W4   SubWdSub2.

この例でわかるように、4つの単語(「Word」、「W2」、「W3」、および「W4」)があり、それぞれサブワードの数が異なります。「Word」のサブワードは「Sub1」と「Sub2」です。「W3」にはサブワードがなく、W4には2つ(「SubWd」と「Sub2」)があります。

したがって、そのファイルを書き出すには、次のようにすることができます。

Private Sub SaveWords(filePath As String, words As List(Of Word))
    Const maxLength As Integer = 100
    Using writer As New StreamWriter(filePath)
        Dim firstWord As Boolean = True
        For Each w As Word in words
            If firstWord Then
                firstWord = False
            Else
                writer.WriteLine()
            End If
            writer.Write(w.theWord.PadRight(maxLength))
            For Each s As SubWord In w.SubWords
                writer.Write(s.theWord.PadRight(maxLength))
            Next
        Next
    End Using
End Sub
于 2012-11-17T18:59:58.680 に答える