I'm doing a C program, in which I want to shuffle an array (or part of an array). Here is the array:
string colorTheme[8][8] = {
{"blue", "blue", "green", "green", "violet", "violet", "teal", "teal"},
{"beige", "beige", "red", "red", "indigo", "indigo", "pink", "pink"},
{"cyan", "cyan", "yellow", "yellow", "orange", "orange", "azure", "azure"},
{"purple", "purple", "lime", "lime", "tangerine", "tangerine", "fuschia", "fuschia"},
{"brown", "brown", "gray", "gray", "black", "black", "white", "white"},
{"olive", "olive", "crimson", "crimson", "silver", "silver", "gold", "gold"},
{"maroon", "maroon", "coral", "coral", "plum", "plum", "ivory", "ivory"},
{"aqua", "aqua", "jade", "jade", "amber", "amber", "ruby", "ruby"}
};
If I wanted to shuffle the first n rows and n columns, how would I do it? Ideally, I would run
shuffle(n);
because colorTheme is in the same class as shuffle().
CodePudding user response:
You can't shuffle const array, but you can do it by changing it, I will post an example of shuffling a 2d array, you can refer that if you want to:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <algorithm>
#include <iterator>
int main()
{
// the hard, inefficient way
{
enum { N = 7, M = 13 } ;
char dest[N][M] = { "zero", "one", "two", "three", "four", "five", "six" } ;
std::srand( std::time(nullptr) ) ;
for( int i = N-1 ; i > 0 ; --i ) // fisher yates shuffle
{
const int pos = std::rand() % (i 1) ;
char temp[M] ;
std::strcpy( temp, dest[pos] ) ;
std::strcpy( dest[pos], dest[i] ) ;
std::strcpy( dest[i], temp ) ;
}
for( const char* cstr : dest ) std::cout << cstr << ' ' ;
std::cout << '\n' ;
}
// the simple, efficient way
{
enum { N = 7 } ;
std::string dest[N] = { "zero", "one", "two", "three", "four", "five", "six" } ;
std::srand( std::time(nullptr) ) ; // if it has not already been done
std::random_shuffle( std::begin(dest), std::end(dest) ) ;
for( const std::string& str : dest ) std::cout << str << ' ' ;
std::cout << '\n' ;
}
}
CodePudding user response:
The best way to tackle this problem is to convert the 2D array into 1D, as shuffling a 1D array is a lot simpler. Under the covers, create an int array shuffler; fill an int array with values from 0 - n^2 and shuffle them using something like rand. From there, use the values in the int array as new positions for your string array. Once you have shuffled your string array, convert it back into a 1D array. Here is a simple c source file I created (feel free to use).
#include <iostream>
#include <string>
using namespace std;
void shufflePos(int n, int arr[]);
void printArray(int *a, int length) {
cout << "[ ";
for (int i = 0; i < length; i ) {
cout << a[i];
if (i != length - 1) {
cout << ", ";
}
}
cout << " ]\n";
}
void shufflePos(int n, int arr[]) {
for(int i = 0; i < n; i ) {
arr[i] = i;
}
// shuffle positions
srand(time(0));
for(int i = 0; i < (n - 2); i ) {
/*if(arr[i] != i) // i has already been swapped
continue;
*/
int tmp = arr[i];
// cout << "i = " << i << ", n - i = " << (n - i) << ", ";
int random = rand();
// cout << "random = " << random << ", ";
int nextPos = i random % (n - i);
// cout << "nextPosition = " << nextPos << endl;
arr[i] = arr[nextPos]; // swap
arr[nextPos] = tmp;
}
//printArray(arr, n);
/* bool chck = check(arr, n);
if(chck == false)
cout << "FALSE" << endl;
else
cout << "TRUE" << endl; */
}
void swapString(string arr[], int pos1, int pos2) {
string tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
return;
}
void shuffleString(string strs[], int len) {
int valArr[len];
shufflePos(len, valArr);
string to[len];
// copying values into another array
for(int i = 0; i < len; i ) {
to[i] = strs[valArr[i]];
}
// copying to[] into strs[]
for(int i = 0; i < len; i ) {
strs[i] = to[i];
}
}
int main() {
string colorTheme[8][8] = {
{"blue", "blue", "green", "green", "violet", "violet", "teal", "teal"},
{"beige", "beige", "red", "red", "indigo", "indigo", "pink", "pink"},
{"cyan", "cyan", "yellow", "yellow", "orange", "orange", "azure", "azure"},
{"purple", "purple", "lime", "lime", "tangerine", "tangerine", "fuschia", "fuschia"},
{"brown", "brown", "gray", "gray", "black", "black", "white", "white"},
{"olive", "olive", "crimson", "crimson", "silver", "silver", "gold", "gold"},
{"maroon", "maroon", "coral", "coral", "plum", "plum", "ivory", "ivory"},
{"aqua", "aqua", "jade", "jade", "amber", "amber", "ruby", "ruby"}
};
cout << "What size of array do you want?" << endl;
int i;
cin >> i;
int n = i * i; // length of 1D array
string darr[n]; // 1D array
for(int r = 0; r < i; r ) { // fill values of 1D array // rows
for(int c = 0; c < i; c ) { // columns
darr[(i * r c)] = colorTheme[c][r];
}
}
cout << 1 << endl;
shuffleString(darr, n);
cout << 2 << endl;
// convert 1D array back into 2D array
for(int r = 0; r < i; r ) {
for(int c = 0; c < i; c ) {
colorTheme[c][r] = darr[(i * r) c];
}
}
for(int r = 0; r < i; r ) { // rows
for(int c = 0; c < i; c ) { // columns
cout << ": " << colorTheme[c][r] << " ";
}
cout << endl;
}
}
