Home > Blockchain >  Shuffle a 2D string array
Shuffle a 2D string array

Time:07-26

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;
    }
}
  • Related