3

I read lines from txt file. They are about 100 000. How to fill queue and shuffle its elements? Fill queue like this:

    Queue<string> accs = new Queue<string>();
    private void loadLikeAccountsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.RestoreDirectory = true;
        openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            accs.Clear();

            foreach (string s in File.ReadAllLines(openFileDialog1.FileName))
            {
                accs.Enqueue(s);
            }
            label4.Text = accs.Count.ToString();
        }
    }
Kenji
  • 73
  • 1
  • 8
  • 10
    If you shuffle a queue after you fill it, than is it still truly a queue? – Sam I am says Reinstate Monica Jul 29 '13 at 19:01
  • First in, `new Random.Next()` out? – Mike G Jul 29 '13 at 19:02
  • It sounds like you are looking for a list or array - this is not what a queue is intended for. – tsells Jul 29 '13 at 19:03
  • 4
    You should not use a `Queue` if your end goal is to shuffle it anyway. A `List` would be enough. Look at this SO: [Randomize a List in C#](http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp) – Simon Belanger Jul 29 '13 at 19:03
  • 4
    @mikeTheLiar So is that FIRO? – Kevin Jul 29 '13 at 19:03
  • I wonder what the most efficient method of doing this is. Currently thinking of using a binary tree but using a rand(2) instead of strcmp() to determine how to insert new elements. – Skizz Jul 29 '13 at 19:12
  • just use an array or linked-list and take out elements at random and move them to the end of the collection. Need also to keep track of the index which denotes separation between 'fresh' and already chosen items. – Adrian Jul 29 '13 at 19:24

4 Answers4

7

A queue is for FIFO. You're asking for something other than FIFO. So, you're using the wrong tool for the job.

A simple approach is instead of filling a queue, fill a list, and then shuffle the elements of the list.

Community
  • 1
  • 1
jason
  • 236,483
  • 35
  • 423
  • 525
1

This is working with my array:

Queue<string> arrProvincies = new Queue<string>(File.ReadAllLines(@"provincies.txt").OrderBy(o => new Guid()));
Gekkehond
  • 128
  • 1
  • 13
0

If you want a queue to have the lines from random parts of the file then you should fill a list with the file's lines then shuffle it and then after insert the values the list into a queue creating the end result of what you described.

SteveKB
  • 190
  • 6
-1

Try something like this:

class Program
{
  static void Main( string[] args )
  {
    string myFileName = @"c:\foo\bar\baz.txt" ;
    Queue<string> queue = new Queue<string>( File.ReadAllLines(myFileName).Shuffle() ) ;
  }
}
/// <summary>
/// A few helper methods
/// </summary>
static class ExtensionMethods
{
  /// <summary>
  /// Performs an in-place shuffle of an array
  /// </summary>
  /// <typeparam name="T"></typeparam>
  /// <param name="instance"></param>
  /// <returns></returns>
  public static T[] Shuffle<T>( this T[] instance )
  {
    for ( int i = 0 ; i < instance.Length ; ++i )
    {
      int j = rng.Next(i,instance.Length ) ; // select a random j such that i <= j < instance.Length

      // swap instance[i] and instance[j]
      T x = instance[j] ;
      instance[j] = instance[i] ;
      instance[i] = x ;

    }

    return instance ;
  }
  private static readonly Random rng = new Random() ;

}

But why use a Queue<T>? at all? Something like this is simpler and more straightforward:

List<string> shuffledLines = new List<string>( File.ReadAllLines(fn).Shuffle() ) ;
.
.
.
// we iterate over the shuffled list in reverse order so as to 
// shrink the list in place rather than remove the leftmost item
// and moving the remainder wholesale on each iteration.
for ( int i = --shuffledLines.Length ; i >= 0 ; --i )
{
  string s = shuffledLines(i) ;
  shuffledLines.RemoveAt(i) ;

  DoSomethingUseful( s ) ;

}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135