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().
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' ;
}
}
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
When creating and duplicating the matrix, it writes it the way I want, my question is how can I eliminate the duplicate elements of matrix1 because I need it to only show me the values of the matrix without showing the duplicates. It would be more or less as follows.
enter number of rows: 3.
enter number of columns: 4.
Original Array:.
3 7 14 2.
6 2 3 15.
10 8 11 6.
Result Array:
3.
7.
14.
2.
6.
15.
10.
8.
11.
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
int f = 0;
int c = 0;
cout<<"Ingresar numero de filas: ";
cin>>f;
cout<<"Ingresar numero de columnas: ";
cin>>c;
int matriz[f][c];
int matriz1[f][c];
srand(time(0));
for (int i = 0 ; i < f; i++ )
for (int j = 0 ; j < c ; j++ )
matriz[i][j] = 1 + rand()% 15;
cout<< "Arreglo Original"<< endl;
for (int i = 0 ; i < f; i++ ){
for (int j = 0 ; j < c ; j++ ){
cout<<matriz[i][j]<<" "; }
cout<< endl;
}
cout<< "Arreglo resultante "<<endl;
for (int i = 0 ; i < f; i++ ){
for (int j = 0 ; j < c ; j++ ){
matriz1[i][j] = matriz[i][j];
cout<< matriz1[i][j]<<endl;}
}
return 0;
}
Here you are:
#include <vector>
#include <memory>
#include <bitset>
#include <algorithm>
#include <iterator>
#include <iostream>
int main() {
std::vector<std::vector<int>> example{
{ 3, 7, 14, 2 },
{ 6, 2, 3, 15 },
{ 10, 8, 11, 6 }
};
int const max = 15; // while reading example find out max
auto is_avail = std::make_unique<std::bitset<max + 1>>();
std::vector<int> ans;
for (auto const& v : example) {
for (auto const e : v) {
if (!is_avail->test(e)) {
ans.emplace_back(e);
is_avail->set(e, true);
}
}
}
std::copy(ans.cbegin(), ans.cend(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
In case you want ans to be 2D too replace the code following the line
auto is_avail = std::make_unique<std::bitset<max + 1>>();
with
std::vector<std::vector<int>> ans{ example };
for (auto& v : ans) {
for (auto& e : v) {
if (!is_avail->test(e)) {
is_avail->set(e, true);
}
else {
e = -1; // error state
}
}
}
for (auto const& v : ans) {
for (auto const e : v) {
if (e != -1) {
std::cout << std::setw(2) << e;
}
else {
std::cout << std::setw(2) << ' ';
}
std::cout << '\t';
}
std::cout << '\n';
}
and don't forget to
#include <iomanip>
for std::setw.
I am trying to figure out how to print all the combinations in c++.
Given input is {"abc","xyz"} and desired output is {"ax", "ay", "az", "bx", "by", "bz", "cx", "cy","cz"}
I found this recursion code snippet :
`#include <bits/stdc++.h>
using namespace std;
void printKLengthString(char set[], string sequence, int n, int k) {
if (k == 0){
cout<<sequence<<"\t";
return;
}
for (int i = 0; i < n; i++){
string newSequence;
newSequence=sequence+set[i];
printKLengthString(set, newSequence, n, k - 1);
}
}
int main() {
char set[] = {'a', 'b'};
int n = 2;
int k = 3;
printKLengthString(set, "", n, k);
}`
but I am not able to manipulate it according to my desired inputs
Update 1:
Here is my code:
`#include <bits/stdc++.h>
using namespace std;
void printKLengthString(vector<char> set, string sequence, int n, int k) {
if (k == 0){
cout<<sequence<<"\t";
return;
}
for (int i = 0; i < n; i++){
string newSequence;
newSequence=sequence+set.at(i);
printKLengthString(set, newSequence, n, k - 1);
}
}
int main() {
vector<string> stringIn = {"ab", "xy"};
// int n = 2;
// int k = 2;
// for (int i = 0; i < set.size(); i++) {
// cout << set[i] << "\n";
// }
vector<char> set;
for (int i = 0; i < stringIn.size(); i++) {
for (int j = 0; j < stringIn[0].size(); j++) {
// cout << stringIn[i].at(j) << "\n";
// str += char(set[i].at(j));
set.push_back(stringIn[i].at(j));
}
}
// for (char k: set) {
// cout << k << "\t";
// }
cout << "\n";
// cout << "stringIn Size : " << stringIn.size() << "\n";
// cout << "set Size : " << set.size() << "\n";
int k = stringIn.size();
int n = set.size();
printKLengthString(set, "", n, k);
}`
I am getting output as :
aa ab ax ay ba bb bx by xa xb xx xy ya yb yx yy
which is permutation but I just want the combination , which I am not able to figure out..
Anyone could guide me?
Update 2: I want to scale this for multiple inputs, e.g. {"abc","def","ghi","xyz"}
const unsigned int n1 = strlen(s1);
const unsigned int n2 = strlen(s2);
for (unsigned int i1=0;i1<n1;i1++)
{
for (unsigned int i2=0;i2<n2;i2++)
{
printf("%c%c\n",s1[i1],s2[i2]);
}
}
Draw 2 cards from the deck and check if they are a pair (having the same rank). Repeat this at least 1000 times and calculate the probability of drawing a pair from a deck of cards.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
int counter;
string facevalue[] = { "Two", "Three", "Four", "Five", "Six", "Seven", "Eight","Nine", "Ten", "Jack", "Queen", "King", "Ace" };
string suit [] = { "Diamonds", "Hearts", "Spades", "Clubs" };
string getcard() {
string card;
int cardvalue = rand() % 13;
int cardsuit = rand() % 4;
card += facevalue[cardvalue];
card += " of ";
card += suit[cardsuit];
if(cardvalue = cardvalue){
counter = counter + 1;
}
return card;
}
int main() {
int numberofcards = 2;
int times = 1000;
for (int y =0; y < times; y++){
cout<<" "<<endl;
for (int i = 0; i < numberofcards; i++) {
cout << "You drew a " << getcard() << endl;
}
}
cout<<"counter: "<<counter<<endl;
}
So here, cardvalue controls what gets printed out from the array. So if cardvalue is 1 then facevalue[cardvalue] will be facevalue[1], which will print out "Two."
So right now I am trying to determine how many times will cardvalue be the same when picking 2 cards randomly from the deck.
I did
if(cardvalue = cardvalue){
counter = counter + 1;
}
The result I get is 926, meaning there are 926 times that the card value will be the same when drawing 2 cards out of a deck 1000 times. That doesn't seem right, would be much appreciated if anyone can correct my program or guide me through the process.
I tried (cardvalue == cardvalue)
but I get counter : 2000 instead.
If you work directly with index instead of string, you may have something like:
int color_of_card(int i)
{
return i / 13;
}
int value_of_card(int i)
{
return i % 13;
}
std::string card_as_string(int i)
{
static const std::string facevalues[] = {
"Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"
};
static const std::string suits[] = { "Diamonds", "Hearts", "Spades", "Clubs" };
return facevalues[value_of_card(i)] + " of " + suits[color_of_card(i)];
}
int getcard() {
return rand() % 52;
}
int main() {
const int times = 1000;
int counter = 0;
for (int y = 0; y != times; y++)
{
auto card1 = getcard();
auto card2 = getcard();
while (card1 == card2) { card2 = getcard(); } // Ensure cards differ.
if (value_of_card(card1) == value_of_card(card2)) {
++counter;
}
}
std::cout << counter << std::endl; // 58 or 59 normally
// Once you took a card, there are only 3 card on same value
// and there is 51 remaining cards.
std::cout << 3 / 51.f << std::endl; // 0.0588235
}
Demo
First remove your global counter variable, it is a bad practice.
Then you may try something like that :
int main() {
int numberofcards = 2;
int times = 1000;
int counter = 0;
std::map<string, int> cardMap;
string currentCard;
int maxNbSameCard;
for (int y =0; y < times; y++){
cardMap.clear();
maxNbSameCard = 0;
for (int i = 0; i < numberofcards; i++) {
currentCard = getcard();
cardMap[currentCard]+=1;
cout << "You drew a " << currentCard << endl;
cout << "It is the " << cardMap[currentCard] << " time you get this card" << endl;
if(maxNbSameCard < cardMap[currentCard]) maxNbSameCard = cardMap[currentCard];
}
if(maxNbSameCard > 1) ++counter;
}
cout<<"counter: "<<counter<<endl;
}
note that "=" is an affectation not a comparison.
it's not the job of getcard() to count pairs, it is only a card creator, it has no visibility about previously created cards.
Help me to get correct result with this cplusplus program.
With this code I'm trying to print all the elements in array 'arr' with each inner array on it's own line.
Code:
using namespace std;
int main()
{
int arr[3][4] = {
{1,2,3,4},{5,6,7,8},{9,10,11,12}
};
for (auto p = begin(arr); arr != end(arr); ++p) {
for (auto q = begin(*p); q != end(*p); ++q) {
cout << *q << " ";
}
}
cout << endl;
keep_window_open();
return 0;
}
But when I execute this code the compiler shows me a bunch of memory addresses instead elements in array 'arr'. Did I do anything wrong with that code? And I'm using Visual Studio 2015 for programming, In case if you want to know.
try this:
int ia[3][4] = {
{ 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }
};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
cout << ia[i][j] << endl;
}
}
Just for Fun
#include <iostream>
#include <array>
int main(void)
{
std::array<std::array<int, 4>, 3> const array = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}};
if (array.begin() != array.end()) {
auto itarray = array.begin();
if (itarray->begin() != itarray->end()) { {
auto itsubarray = itarray->begin();
std::cout << *itsubarray;
for (itsubarray = itsubarray + 1; itsubarray != itarray->end(); itsubarray++) {
std::cout << " " << *itsubarray;
} }
for (itarray = itarray + 1; itarray != array.end(); itarray++) {
for (int elem : *itarray) {
std::cout << " " << elem;
}
}
}
}
std::cout << std::endl;
return 0;
}
Or if you wish to use iterators:
#include <iterator>
using std::endl;
using std::begin;
using std::end;
using std::cout;
int main() {
int arr[3][4] = { { 1,2,3,4 },{ 5,6,7,8 },{ 9,10,11,12 } };
for (auto p = begin(arr); p != end(arr); ++p) {
for (auto q = begin(*p); q != end(*p); ++q) {
cout << *q << " ";
}
}
cout << endl;
return 0;
}
The change is in the first for loop where you had arr != end(arr), but you wanted p != end(arr). And if you ever change the length of your array this loop will still work.
What I am trying to achieve is this:
I have an image and I need to split it into sub blocks of 16x16 and I am working on the algorithm for this. For testing purposes though, I am using a small matrix:
A = {1, 2, 3, 4}
Now what I want to end up is this: 2 blocks containing:
A[1] = {1 2};
A[2] = {3, 4};
I have tried to use the following:
double matrix[4] = {1, 2, 3, 4};
for(int i = 0; (i < 4); i++)
{
for(unsigned j=i; (j < 2); j +=2)
{
std::cout << j << ' ';
}
std::cout << std::endl;
}
My thought process was to loop through the entire array (4) and then increment by 2 each time to create the 1x2 block. This did not work however.
Where am I going wrong here?
Something like that? (Does both output and assignment)
int LEN = 4;
int INNER = 2;
int OUTER_LEN = LEN/INNER_LEN;
double matrix[LEN] = {1, 2, 3, 4};
double* matrix2[OUTER_LEN];
for(int i = 0; i < OUTER_LEN; i++)
{
matrix2[i] = &matrix[i*INNER_LEN];
for(unsigned j=0; j < INNER_LEN; j++)
{
std::cout << matrix[i*INNER_LEN+j] << ' ';
}
std::cout << std::endl;
}
Just for output you could do something like that:
#include <iostream>
int main(){
const size_t SIZE = 4;
const size_t PART_SIZE = 2;
double matrix[4] = {1, 2, 3, 4};
for(int i = 0; (i < SIZE); i += PART_SIZE)
{
for(size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1)
{
std::cout << matrix[j] << ' ';
}
std::cout << std::endl;
}
}
To add another matrix:
#include <iostream>
int main(){
const size_t SIZE = 4;
const size_t PART_SIZE = 2;
size_t partsNumber = SIZE / PART_SIZE; // Beware of SIZE that is not divisible by PART_SIZE - partsNumber will be too small
double matrix[4] = { 1, 2, 3, 4 };
// To do it properly I should make it dynamic array with size of partsNumber instead of the 2 literals
double parts_matrix[2][PART_SIZE];
for (int i = 0; (i < SIZE); i += PART_SIZE) {
for (size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1) {
std::cout << matrix[j] << ' ';
parts_matrix[j / partsNumber][j % PART_SIZE] = matrix[j];
}
std::cout << std::endl;
}
std::cout << parts_matrix[0][0] << " " << parts_matrix[0][1] << std::endl << parts_matrix[1][0] << " " << parts_matrix[1][1]; // Check if it works
}
The following is a demo of how to do the splitting for custom block size (rough cut though, corner cases and input verification are ommited) using boost range and the boost::slice functionality (here "output creation" is presented)
#include <iterator>
#include <iostream>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>
using namespace std;
using namespace boost::adaptors;
template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
for (size_t i(0); i <= N-block_size; i += block_size)
{
cout << "{ ";
boost::copy(input | sliced(i, i+block_size),
std::ostream_iterator<int>(std::cout, " "));
cout << "}\n";
}
}
int main()
{
int A[] = {1, 2, 3, 4};
split(A, 2);
}
Demo
Output
{ 1 2 }
{ 3 4 }
What if I don't want to do output
To some the following may look more readable
template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
for (size_t i(0); i <= N-block_size; i += block_size)
{
cout << "{ ";
// do whatever with the i slice (again I'm showing output)
for (auto k : (input | sliced(i, i+block_size))) cout << k << " ";
cout << "}\n";
}
}