Hi there,

I am working with a 2D array, my c++ program reads input from an external file and stores it into a 2D array. Say, for example, this is my input file:

9 5 6 2
4 1 0 8
6 7 3 5
2 9 5 8

My problem is I want to randomly shuffle only the rows so I get row 1 [9 5 6 2] somewhere in maybe row 3 and row 3 is found somewhere in row 2 and so forth, where my columns are kept intact. Most searches online give me how to shuffle the elements in a row - random shuffling of rows AND columns. However, below is what I've done so far to get the values that were repeating themselves but it was obvious from my output that shuffling of columns were done as well-which is what I do NOT want.

What I want to know is if I'm on the right track, then what am I doing wrong? Or where am I going wrong?

Here's what my shuffling code looks like given my variables and array were defined and initialized and I've read from input file:

int r;
  int t;

  for(int k=0;k<4;k++){
      for(int m=0;m<4;m++){
          r=rand()%4;

          t=rri_val[k][m];
          rri_val[k][m]=rri_val[r][m];
          rri_val[r][m]=t;

          cout<<rri_val[k][m]<<" ";

      }

  }

I need clarifications asap... Thanks,
Lee

First get your swap correct. You can't sort, shuffle or do anything with rows till your swap is correct. If rows are considered elements, then you can't split them up. That means that in order to swap, you have to either loop through the row one element at a time and swap the whole row or you can take advantage of the fact that rows are contiguous in memory and treat it like any other swap and swap the whole row at once using memcpy or memmove.

Line 7 needs to be OUTSIDE of the inner loop. You are always swapping FOUR elements at a time and they'd better be from the same row. Line 13, unless it's purely for debugging purposes, should not be inside of this swapping routine. Swap or print, but don't print from WITHIN a swap unless you're using it purely as a debugging technique.

int array[4][4]; // fill this in however you want.
int rowIndex1 = 2; // randomly generate this index
int rowIndex2 = 3; // randomly generate this index
int temp; // for use in the swap below
for(int column = 0; column < 4; column++)
{
    // now swap array[rowIndex1][column] and array[rowIndex2][column]
}

Rows 2 and 3 are now swapped.

You will have to use two temp arrays

(1) and array that contains the random numbers so that when a random number is generated the program searches this array to see if it has already been used. If the new random number already exists in the array then go back and generate another random number.

(2) You can not shuffel the rows directly into the original array because moving one of the rows will overwrite the values in the destination row, and the values in the destination row will be lost forever. Create a new temp array to hold the shuffled rows, then after the shuffling is complete copy the data in the temp array back into the original array.

Thanks heaps guys for the fast response,

Will work on it and get back if I'm still stuck...

:)
L8rz

Okay,

So I've come up wif this:

float t1, t2;

  //int k=rand()%63;
  for(int k=0;k<63;k++){
          int r2=rand()%63;
      for(int m=0;m<4;m++){

         t1=rri_val[k][m];
         t2=rri_val[r2][m];
         rri_val[r2][m]=t1;
         rri_val[k][m]=t2;

         outfile <<rri_val[k][m]<<" "; //For debugging
     }
      outfile << endl;
  }

When I view the outfile, it contained 63 rows, but with some rows duplicating themselves... I guess it's because the rand() function randomly selects and might pick the same number the next time around. I don't want my program to do that, I just want it to reshuffle the rows all over so that I have exactly 63 unique rows being shuffled into their new positions. For example, I can have row 5 at row position 57, row 57 at position 42, row 42 at position 1, row 1 at position 32, and so forth. Right now, my program is swapping row 1 to row position 44, row 44 to position 1, row 2 to position 3, row 3 to position 2, Row 4 is at position 5 and row 5 at position 4 and so on. Is there another way of shuffling, either than swapping rows as I've done above, and without duplicating a row quite a number of times?

Or am I wrong somewhere again?

Okay, I didn't try Ancient Dragon's first option... Thanks... Will be back later...

I'll reiterate my prior advice...

Line 13, unless it's purely for debugging purposes, should not be inside of this swapping routine. Swap or print, but don't print from WITHIN a swap unless you're using it purely as a debugging technique.

The red part needs to be clarified. Use it for debugging purposes, but don't expect it to not duplicate anything. Your code actually looks just fine to me. The random shuffling part, that is. I'm not guaranteeing there are no problems, but it looks fine.

That said, the fact that you appear to have duplicate rows IN THE FILE doesn't surprise me. I'll be more surprised if you have duplicate rows in memory once you're all done. Again, I'm not guaranteeing. Shuffle, then output. Output WITHIN the shuffle yields God only knows.

float t1, t2;
 
    // shuffle
    for(int k=0;k<63;k++){
        int r2=rand()%63;
        for(int m=0;m<4;m++){
            t1=rri_val[k][m];
            t2=rri_val[r2][m];
            rri_val[r2][m]=t1;
            rri_val[k][m]=t2;
        }
    }
 
    // display
    for(int k=0;k<63;k++){
        for(int m=0;m<4;m++){
            outfile <<rri_val[k][m]<<" ";
        }

        outfile << endl;
    }

See if that works better.

>> but with some rows duplicating themselves... I guess it's because the rand() function randomly selects and might pick the same number the next time around.

That won't accidentally duplicate anything. See my last post. Some of the concern may go away. Possibly not all.


>> Right now, my program is swapping row 1 to row position 44, row 44 to position 1, row 2 to position 3, row 3 to position 2, Row 4 is at position 5 and row 5 at position 4 and so on. Is there another way of shuffling?

Yes there are. See my code snippets here.
http://www.daniweb.com/software-development/cpp/code/217217
http://www.daniweb.com/software-development/cpp/code/217346


If you want to retain your own code, my advice would be to go through the process several times, just like with a real deck of cards. It'll end up being more random.

float t1, t2;
 

    // shuffle
    for(int i = 0; i < 100; i++){ // 100 is just a big number
        for(int k=0;k<63;k++){
            int r2=rand()%63;
            for(int m=0;m<4;m++){
                t1=rri_val[k][m];
                t2=rri_val[r2][m];
                rri_val[r2][m]=t1;
                rri_val[k][m]=t2;
            }
        }
    }
 
    // display
    for(int k=0;k<63;k++){
        for(int m=0;m<4;m++){
            outfile <<rri_val[k][m]<<" ";
        }

        outfile << endl;
    }

Thanks heaps VernonDozier for your clarifications... Very clear this time around :) Oh and thanks for the code snippet posts... They will help me a great deal... Be back to confirm if I get the program to work this time around... Thanks heaps!

Yes, finally, after slowly going through your[VernonDozier] code snippets, I managed to get all my 63 rows shuffled correctly without any duplicated rows and with all columns intact... Thanks heaps...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.