int array[3][3][8] = {
{{3, 4, 5}, {3, 5, 7}, {5, 6, 7}},
{{1, 3, 5}, {0, 1, 2, 3, 4, 5, 6, 7}, {1, 5, 7}},
{{1, 2, 3}, {1, 3, 7}, {0, 1, 7}}
};
User inputs x,y coordinate and direction, at that location they can only move in 0-7 direction. However, each location can only move towards certain direction. Therefore I am making this array to see if that direction is in that x, y coordinate’s array. After I get the 3rd dimension array (becomes 1d array), I will see if user input direction is in that array.
For example:
{3,4,5} at 1x1 // then check if direction is in this array
I tried:
int new_array[8] = array[1][1];
Error: array must be initialized with a brace-enclosed initializer
int new_array = array[1][1][]; // {3,4,5}
Error: expected primary-expression before ']' token
So I know this syntax isn't valid, are there other ways to achieve such operation?
To copy the 3rd dimension array into a new array.
You could use std::copy:
#include <algorithm>
#include <iterator>
//...
int new_array[8];
std::copy(std::begin(array[1][1]),
std::end(array[1][1]),
new_array);
Done using std::array:
#include <array>
// ...
std::array<std::array<std::array<int, 8>, 3>, 3> array = {{
{{
{3,4,5},
{3,5,7},
{5,6,7}
}},
{{
{1,3,5},
{0,1,2,3,4,5,6,7},
{1,5,7}
}},
{{
{1,2,3},
{1,3,7},
{0,1,7}
}},
}};
std::array<int, 8> new_array = array[1][1];
// the same result but simpler:
auto new_array = array[1][1];
there is no way you can get the col or row of an array like that...
if you define a primitive array then you have to navigate the cells and asign the values
int main() {
int test[2][3][2] = {
{
{1, 2},
{3, 4},
{5, 6}
},
{
{7, 8},
{9, 10},
{11, 12}
}
};
int z[2];
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 2; ++k) {
z[k] = test[i][j][k];
}
}
}
for (int k = 0; k < 2; ++k)
{
cout << "z[" << k << "] = " << z[k] << endl;
}
return 0;
Related
I am trying to sort a c++ subarray by first element.
My code is currently set up like this:
int umbrellas[3][2] = {{5, 6}, {2, 7}, {9, 20}};
int n = sizeof(umbrellas) / sizeof(umbrellas[0]);
sort(umbrellas, umbrellas + n, greater<int>());
The sort function doesn't seem to be functioning properly and when I run the code it generates errors. Is there a way to sort the array from
{{5, 6}, {2, 7}, {9, 20}}
into
{{2, 7}, {5, 6}, {9, 20}}
?
Use a std::vector of std::vector as your container and the sort becomes much easier to do with. Not only is std::vector the preferred container for C++ but using STL functions on it is way simpler and direct , without any substantiable overhead.
Define your data as
std::vector<std::vector<int>> umbrellas{
{5, 6},
{2, 7},
{9, 20}
};
Now you can use a custom comparator lambda that takes in two vector element references and returns True when the first element of the above vector is smaller than that of the one below.
std::sort(umbrellas.begin(),
umbrellas.end(),
[](const std::vector<int> &above, const std::vector<int> &below)
{
return (above[0] < below[0]);
});
And the output :
for (auto &&row : umbrellas) {
for (auto element : row) {
std::cout<< element<< " ";
}
std::cout<< "\n";
}
2 7
5 6
9 20
Taking this to C++20 it's even easier:
std::ranges::sort(umbrellas, std::less(),
[](const auto &v) { return v[0];});
If time complexity doesn't matter, this code will achieve the desired with O(n^2) complexity
int arr[3][2] = {{5, 6}, {2, 7}, {9, 20}};
int n = sizeof(arr) / sizeof(arr[0]);
for(int i = 0 ; i < n - 1; i++){
for(int j = 0 ; j < n - 1 ; j++){
if(arr[j][0] > arr[j + 1][0])
swap(arr[j],arr[j + 1]);
}
}
Is this is the right way to store and print?
int array[5];
int a1[3][3], a2[3][3], a3[3][3], a4[3][3], a5[3][3];
int array[0] = a1[3][3];
int array[1] = a2[3][3];
int array[2] = a3[3][3];
int array[3] = a4[3][3];
int array[4] = a5[3][3];
for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
a1[i][j] = 0;
}
}
Similarly, filling the rest arrays.
Now Printing,
for(int i=0;i<5;i++) {
cout<<array[i];
}
did n't get the expected output.
How to print the a1,a2,a3,a4 and a5 from array?
So instead of using old plain c-arrays, use the in-build C++ std::array, if you want fixed-sized arrays. If the range should be dynamic you can switch std::array with std::vector. Look up the different definitions:
#include <array>
#include <iostream>
// a 2D-array is nothing else, than an array containing anotehr array
// what we do, is to define an array with size 3 containing an array with size 3
// this equals int a[3][3];
// this we do 5 times as requested
std::array<std::array<int, 3>, 3> a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::array<std::array<int, 3>, 3> a2 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::array<std::array<int, 3>, 3> a3 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::array<std::array<int, 3>, 3> a4 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::array<std::array<int, 3>, 3> a5 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// now for the array which should contain the other arrays:
// we define a size of 5
// and it should contain the array which contains the array both of size 3
std::array<std::array<std::array<int, 3>, 3>, 5> the_array;
int main() {
// we directly assign the array specifier to the value
// which should contain the specified array
the_array[0] = a1;
the_array[1] = a2;
the_array[2] = a3;
the_array[3] = a4;
the_array[4] = a5;
// now we cannot print the arrays at once,
// we have to iterate "down" to the int to print it
for(auto sub_array2D : the_array) { // iterate over the array containing the 5 arrays
for(auto sub_array1D : sub_array2D) { // now iterate over one array in the array of the 2d array
for(auto elem : sub_array1D) { // at last, access the int element and print it out
std::cout << elem << " ";
}
std::cout << "\t"; // formatting
}
std::cout << "\n"; // formatting
}
return 0;
}
I am trying to replace the elements in a 2D vector (vector<vector<int>>). I want to change the elements not only by one value, but by a list, which means, for example, change 1,3,4,5,8,9 to 1,2,3,4,5,6 one-to-one correspondence. I have made a very slow code with double loops. Is there any way to speed up the process, with new function or sort the element? Because my 2D vector is very big, 3*300000 actually. My example code is below:
int myints[] = { 1,3,4,5,8,9 };
int myints2[] = { 1,2,3,4,5,6 };
std::vector<int> vals (myints, myints+6);
std::vector<int> vals2 (myints2, myints2+6);
vector<vector<int>> V0(3);
V0[0]={1,4,5};
V0[1]={3,1,8};
V0[2]={1,9,4};
for (size_t j = 0; j < V0.size(); j++)
{
for (int i = 0; i < vals.size(); i++)
replace(V0[j].begin(), V0[j].end(), vals[i], vals2[i]);
};
The ideal output V0 should be
1 3 4
2 1 5
1 6 3
You can use an unordered_map to replace each value directly, instead of searching through the whole vector for each replacement:
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
unordered_map<int, int> replacements{{1, 1}, {3, 2}, {4, 3}, {5, 4}, {8, 5}, {9, 6}};
vector<vector<int>> v0(3);
v0[0] = {1, 4, 5};
v0[1] = {3, 1, 8};
v0[2] = {1, 9, 4};
for_each(v0.begin(), v0.end(), [&](vector<int>& v)
{
transform(v.begin(), v.end(), v.begin(), [&](int val)
{
auto it = replacements.find(val);
return it != replacements.end() ? replacements[val] : val;
});
});
// Print
for (auto& v : v0)
{
cout << "[ ";
for (auto val : v)
{
cout << val << ", ";
}
cout << "]" << endl;
}
return 0;
}
Output:
[ 1, 3, 4, ]
[ 2, 1, 5, ]
[ 1, 6, 3, ]
In C++17, you may also choose a parallel execution policy in for_each and/or transform, since all the changes can be done in parallel.
Given a vector of vectors, is there an optimal way to determine the index of the vector which holds the global minimum?
What is the complexity in Big-O notation?
#include <algorithm>
#include <iostream>
#include <vector>
unsigned getMinimumIndex(std::vector<std::vector<unsigned>> const& a) {
if (!a.size())
return 0;
unsigned ret = 0; unsigned temp; unsigned global = 1 << 31;
for (std::size_t idx = 0; idx < a.size(); ++idx) {
if ((temp = *std::min_element(std::begin(a[idx]), std::end(a[idx]))) < global) {
global = temp;
ret = idx;
}
}
return ret;
}
int main() {
std::vector<std::vector<unsigned>> a = {{2, 4, 6, 8}, {3, 9, 5, 7},
{3, 4, 4, 3}, {2, 8, 3, 2},
{4, 4, 4, 0}, {1, 2, 3, 4}};
std::cout << getMinimumIndex(a); // 4-th vector posseses the value '0'
return 0;
}
Since neither your vectors nor the numbers inside a vector are sorted, you have to check every number to be the smallest value.
Thus you get a complexity of O(n).
You can either use iterators like you did or simply use 2 for loops and access the vector with a[i][j] (which should be minor faster because of the missing overhead from iterators).
Also - since you only have unsigned int, you can break as soon as you find 0.
I'm looking for some help on a problem that I vaguely inquired about before, which is solving 15-peg solitaire recursively. I keep getting strange errors when I compile and run it, most of them say "stack overflow" or that I'm getting a seg fault. This is what I have so far, where "board[15]" represents the 15 peg board, and "moves[36]" represents all of the possible moves that can be made. The recursion is supposed to spot when there is only one peg left.
#include <iostream>
using namespace std;
void solveGame(int a[15], int b[36][3], int c[15][4]);
void chooseMove (int a[15], int b[36][3], int openSpace, int c[15][4]);
int findEmpty (int a[15]);
int pegCount (int a[15]);
bool isPeg (int peg, int a[15]);
int usedVals[15] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int d = 0;
int index = 0;
int main ()
{
int openSpace = 5;
int board[15]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
board[openSpace] = 0;
int alreadyMoved[15][4];
int moves[36][3] = {{0, 1, 3},
{0, 2, 5},
{1, 3, 6},
{1, 4, 8},
{2, 4, 7},
{2, 5, 9},
{3, 6, 10},
{3, 7, 12},
{3, 1, 0},
{3, 4, 5},
{4, 7, 11},
{4, 8, 13},
{5, 9, 14},
{5, 8, 12},
{5, 2, 0},
{5, 4, 3},
{6, 3, 1},
{6, 7, 8},
{7, 4, 2},
{7, 8, 9},
{8, 4, 1},
{8, 7, 6},
{9, 5, 2},
{9, 8, 7},
{10, 6, 3},
{10, 11, 12},
{11, 7, 4},
{11, 12, 13},
{12, 7, 3},
{12, 8, 5},
{12, 11, 10},
{12, 13, 14},
{13, 8, 4},
{13, 12, 11},
{14, 9, 5},
{14, 13, 12}};
solveGame(board, moves, alreadyMoved);
for (int i = 0; i < 13; i++)
cout << alreadyMoved[i][0] << " " << alreadyMoved[i][1] << " " < <alreadyMoved[i][2] << endl;
return 0;
}
// main recursive function
void solveGame (int a[15], int b[36][3], int c[15][4]
{
int empSpace;
int moveIndex;
if (pegCount(a) < 2) {
cout<<"game over"<<endl;
} else {
empSpace = findEmpty(a);
chooseMove(a, b, empSpace, c);
solveGame(a, b, c);
}
}
// supposed to pick a move that is applicable to the board otherwise it find a new move
void chooseMove (int a[15], int b[36][3], int openSpace, int c[15][4])
{
int i = 0;
while (1) {
if (i < 36 && b[i][2] == openSpace && isPeg(b[i][0],a) && isPeg(b[i][1],a)) {
a[b[i][0]] = 0;
a[b[i][1]] = 0;
a[b[i][2]] = 1;
c[d][0] = b[i][0];
c[d][1] = b[i][1];
c[d][2] = b[i][2];
c[d][3] = i;
d++;
index = 0;
for (int v = 0; v < 15; v++)
usedVals[v] = -1;
break;
} else if (i > 35) {
a[b[c[d-1][3]][0]] = 1;
a[b[c[d-1][3]][1]] = 1;
a[b[c[d-1][3]][2]] = 0;
c[d-1][0] = 0;
c[d-1][1] = 0;
c[d-1][2] = 0;
c[d-1][3] = 0;
usedVals[index] = openSpace;
index++;
int newOpen = findEmpty(a);
chooseMove(a, b, newOpen, c);
}
i++;
}
}
// counts the pegs on the board in order to cancel recursion
int pegCount (int a[15])
{
int count = 0;
for (int i = 0; i < 15; i++)
if (a[i] == 1)
count++;
return count;
}
// finds an empty space that hasn't already been found faulty
int findEmpty (int a[15])
{
for (int i = 0; i < 15; i++) {
for(int j = 0; j < 15; j++) {
if(a[i] == 0 && i != usedVals[j] && usedVals[j] > -1)
return i;
}
}
}
// tests if current index is a peg
bool isPeg (int peg, int a[15])
{
return a[peg] == 1;
}
A quick glance shows a lot of potential problems, but I think it probably boils down to the way you are passing arrays. Arrays are passed by reference and not by value, so the recursive function is working with a single copy of the array, which I don't think is what you want. Therefore you are never finding the ending move, which will get you a stackoverflow from unlimited recursion.
Try allocating a new copy of the arrays at each level of recursion. Some people will want you to use new or malloc for this, because they feel an introduction to C++ should be a trial by fire where you have to master memory management to do anything useful. Instead, I would advise you not to use arrays at all; use a collection class that will work properly when passed by value (I think std::vector of POD will do this) and the collection class will create copies of your arrays the way your code seems to expect.
You may also be having a problem of doing a depth-first search in chooseMove, when you really want a breadth-first search.
Stack overfow when using recursivity is pretty common. This is due to the fact that return values for function calls are stored into the stack, and the stack keeps filling as long as function does not return. If the recursivity goes too deep, you end up filling your whole stack and overflowing it, which also causes SEGV.
Usually you get a stack overflow when your exit condition does not work, but here you are also passing your parameters by value, which might overflow your stack even in normal operation.
I suggest you pass your arrays by reference or better in a std::vector. An std::vector is a small object that holds the real data in a heap allocated space. You can even return those.
I also suggest that you start your program in a debugger, that is the simplest and most effective way to find out what exactly is going wrong.