Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It would be a lot faster if you constructed an index of the file and then searched the index, as with a linear search every search operation is <code>O(n)</code> whereas with an indexed search it's <code>O(n)</code> for constructing the index, but <code>O(log n)</code> or <code>near-O(1)</code> for lookup (depending on how you build your index). The cost is increased memory consumption for the index, but I'd do it like this:</p> <pre><code>private Dictionary&lt;String,List&lt;Int32&gt;&gt; _index = new Dictionary&lt;String,List&lt;Int32&gt;&gt;(); /// &lt;summary&gt;Populates an index of words in a text file. Takes O(n) where n is the size of the input text file.&lt;/summary&gt; public void BuildIndex(String fileName) { using(Stream inputTextFile = OpenFile(...)) { int currentPosition = 0; foreach(String word in GetWords(inputTextFile)) { word = word.ToUpperInvariant(); if( !_index.ContainsKey( word ) ) _index.Add( word, new List&lt;Int32&gt;() ); _index[word].Add( currentPosition ); currentPosition = inputTextFile.Position; } } } /// &lt;summary&gt;Searches the text file (via its index) if the specified string (in its entirety) exists in the document. If so, it returns the position in the document where the string starts. Otherwise it returns -1. Lookup time is O(1) on the size of the input text file, and O(n) for the length of the query string.&lt;/summary&gt; public Int32 SearchIndex(String query) { String[] terms = query.Split(' '); Int32 startingPosition = -1; Int32 currentPosition = -1; Boolean first = true; foreach(String term in terms) { term = term.ToUpperInvariant(); if( first ) { if( !_index.Contains( term ) ) return -1; startingPosition = _index[term][0]; } else { if( !ContainsTerm( term, ++currentPosition ) ) return -1; } first = false; } return startingPosition; } /// &lt;summary&gt;Indicates if the specified term exists at the specified position.&lt;/summary&gt; private Boolean ContainsTerm(String term, Int32 expectedPosition) { if( !_index.ContainsKey(term) ) return false; List&lt;Int32&gt; positions = _index[term]; foreach(Int32 pos in positions) { if( pos == expectedPosition ) return true; } return false; } </code></pre> <p>The implementation of <code>OpenFile</code> and <code>GetWords</code> should be trivial. Note that <code>GetWords</code> uses <code>yield return</code> to build an <code>IEnumerable&lt;String&gt;</code> of whitespace-separated words in the file, as well as dealing with your custom file format.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload