2 Dimensional array initializer list exception - c++

[Exeption]
Hello guys,
I'm trying to make an initializer_list constructor for 2D array.
Any Help, please?
.......................
Matrix(int row,int col,const std::initializer_list<double>& list)
{
rows = row;
cols = col;
std::initializer_list<double>::iterator it;
arr = new double* [rows];
/*double* ptr = arr[k];*/
int n = 0;
for (it = list.begin(); it != list.end(); ++it)
{
int k = 0;
if (n == cols)
{
k++;
n = 0;
}
n++;
arr[k][n] = *it;
}
}

You did not allocate enough memory. Also note that you probably do not want to reset k in every iteration and there are ranged-based loops if you want to do something on the entire container:
//correct allocation
int n = 0;
int k = 0;
for (auto const& number : list) {
arr[k][n] = number;
n++;
if (n == col) {
n = 0;
++k;
}
}
There is also no need to declare variables before you need them. With iterators use for(auto it = list.begin(); it != list.end(); ++it).
Also there is no need for temporary variables when they are function parameters and row and col do not have a type.

Related

Searching in vectors of pairs

I have a 2d vector of pairs and I would like get in which row is a given pair.
I tried to iterate through all the elements but I didn't succeed.
Here is the adjacency matrix of an undirected, weighted graph:
vector<pair<int,int >> adj[20];
for (int i = 1; i <= nodes; i++){
f >> x >> y >> weight;
adj[x].push_back(make_pair(weight, y));
adj[y].push_back(make_pair(weight, x));
}
And it looks like something like this:
(4,2),(5,3)
(4,1),(6,3)
(5,1),(6,2)
I am trying to find in which row is the pair (6,2)
typedef pair<int, int>p;
p pair= make_pair(6, 2);
cout << which_row(adj, pair);
Here is what I tried first:
int which_row(vector<p>adj[20], p pair) {
vector <pair<int, int>> ::iterator it;
for (int i = 0; i < adj->size(); i++) {
for (int j = 0; j < adj[i].size(); i++)
if (pair.first == adj[i][j].first && pair.second == adj[i][j].second)
return i;
}
return -1;
}
but it does not step in the for loop.
Second:
int which_row(vector<p>adj[20], p pair) {
vector <pair<int, int>> ::iterator it;
for (int i = 0; i <= adj->size(); i++) {
for (it = adj[i].begin(); it != adj[i].end(); it++)
if (pair.first == it->first && pair.second == it->second)
return i;
}
}
But it does not step in the second for loop.
What can I do?
Since we can infer your x and y inputs from the pairs you gave us, you never push anything into adj[0]. adj->size() is the same as adj[0].size(). You never pushed anything into this so it will be 0. It seems you want to go over every row? Each row contains a vector? Each vector contains some pairs? Make adj a vector<vector<pair<int, int>>> so you can access adj.size(). That's likely what you want. Or iterate from i = 0; i < 20; i++ to go over each row.
Change your iteration to:
int which_row(vector<p>adj[20], p pair) {
for (int i = 0; i < 20; i++) { // <-- changed to < 20 (not <= 20)
for (auto it = adj[i].begin(); it != adj[i].end(); it++)
if (pair == *it) // <-- pairs compare as you'd expect, no need to compare each element
return i;
}
return -1; // need to return something if not found
}
Or we can take advantage of std::find in the <algorithm> library:
#include <algorithm>
int which_row(vector<p>adj[20], p pair) {
for (int i = 0; i < 20; i++) { // <-- changed to < 20 (not <= 20)
if (std::find(adj[i].begin(), adj[i].end(), pair) != adj[i].end())
return i;
}
return -1; // need to return something if not found
}
If you change your adj initialization to std::vector<std::vector<p>> adj(20); you can change your which_row to:
// in main or whatever:
// makes a vector of 20 default-initialized (empty) vector<p>
std::vector<std::vector<p>> adj(20);
// elsewhere:
int which_row(vector<vector<p>> adj, p pair) {
for (auto i = 0; i < adj.size(); i++) { // <-- adj is a vector now
if (std::find(adj[i].begin(), adj[i].end(), pair) != adj[i].end())
return i;
}
}
return -1; // need to return something if not found
}

Removing odd numbers from an array

I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}
// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}
Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo

Dynamic Programming Solution for TSP in C++

I have been trying to implement Dynamic Programming solution for TSP (Travelling Salesperson Problem) in C++. My code compiles but when I try to run the object file the program stops working and I am forced to close it.
Here is the code:
int tsp(std::vector<std::vector<int>> matrix) {
int n = matrix[0].size();
std::vector<std::vector<int>> A; // Vertex, Set-Size
std::set<int> S;
for(int i = 0; i < n; ++i) {
S.insert(i);
}
for(int i = 0; i < n; i++) {
if(S.size() == 2) {
A[i][2] = matrix[1][i];
}
else if(S.size() > 2) {
std::set<int>::iterator it;
for(it = S.begin(); it != S.end(); ++it) {
int s = S.size();
S.erase(i);
int sd = S.size();
int k = *it;
if((k != i) && (k != 1) && (A[i][s] > (matrix[k][i] + A[k][sd]))) {
A[i][s] = matrix[k][i] + A[k][sd];
}
}
}
}
return A[1][n];
}
Can someone please point out what mistake I am making.
You need to fill or resize a std::vector before calling operator[int] on it. A vector is basically an array that holds its size. So any out of bound access will cause a segmentation fault in runtime (if you are lucky) or will corrupt your memory.
You have a vector of vectors here, so you will need to iterate over two ranges and fill (or resize) vectors properly:
std::vector<std::vector<int>> A; // Vertex, Set-Size
for(int i=size; i>0; --i)
A.push_back(std::vector<int>);
for(int i=size; i>0; --i)
for(int j=size; j>0; --j)
A[i][j] = 0;
Even better:
A.resize(size);
for(auto& v : a) // (since you already have c++11)
v.resize(size, val); // fill with val

Using pointers to iterate through multidimensional array

If you can use pointers to iterate through an array like this:
for (int *iter = arr; iter != std::end(arr); ++iter) {
// code
}
How do you iterate through a multidimensional array with pointers (without using auto)?
EDIT: I am assuming this is an int[][] such as {{3, 6, 8}, {2, 9, 3}, {4, 8, 2}}
If you declared array as arr[][], and yes you can because they are stored sequentially in memory. You can do:
for(int * iter = &arr[0][0]; iter != &arr[0][0] + col * row; iter++)
//...
How about trying like this:-
const int* d = data;
for ( int i = 0; i < width; ++i )
for ( int j = 0; j < height; ++j )
for ( int k = 0; k < depth; ++k )
sum += *d++;
Check this tutorial
For example:
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt] = { // three elements; each element is an array of size 4
{0, 1, 2, 3}, // initializers for the row indexed by 0
{4, 5, 6, 7}, // initializers for the row indexed by 1
{8, 9, 10, 11} // initializers for the row indexed by 2
};
Not using a type alias for the type of the loop control variables:
// p points to the first array in ia
for (int (*p)[colCnt] = ia; p != ia + rowCnt; ++p) {
// q points to the first element of an array of four ints; that is, q points to an int
for (int *q = *p; q != *p + colCnt; ++q)
cout << *q << " ";
cout << endl;
}
or easier using auto:
for (auto p = ia; p != ia + rowCnt; ++p) {
// q points to the first element of an array of four ints; that is, q points to an int
for (auto q = *p; q != *p + colCnt; ++q)
cout << *q << " ";
cout << endl;
}
Improving texasbruce's answer(couldn't comment sorry) with sizeof trick, assuming array is statically allocated(dimensions are known at compile-time)
for(int * iter = &arr[0][0]; iter != &arr[0][0] + sizeof(arr)/sizeof(int); iter++)
or iter != (int*)((void*)&arr[0][0] + sizeof(arr)) if you're (void*) fan and hate any compile-time divisions
So you don't have to bother with array dimensions :)
Probably something like this
for (int **iter = arr; iter != std::end(arr); ++iter) {
for (int *iter2 = *iter; iter2 != std::end(*arr); ++iter2) {
// code
}
}
Assuming you are simply talking about statically declared multi-dimensional arrays:
const int ROWS = 10;
const int COLS = 20;
const int DEPTH = 30;
int array[ROWS][COLS][DEPTH]; // statically allocated array
int i = 0;
for (int row = 0; row < ROWS; ++row)
{
for (int col = 0; col < COLS; ++col)
{
for (int depth = 0; depth < DEPTH; ++depth)
{
*(*(*(array + row) + col) + depth) = i++; // do whatever with it
// is equivalent to array[row][col][depth] = i++;
}
}
}
If you need more levels, you just keep adding levels of pointer indirection.
Alternatively:
const int ROWS = 5;
const int COLS = 6;
const int DEPTH = 3;
int array[ROWS][COLS][DEPTH]; // statically allocated array
int* p = &array[0][0][0];
int c = 0;
for (int i = 0; i < ROWS * COLS * DEPTH; ++i, p++)
{
*p = c++;
}
Since a statically declared array is going to be contiguous in memory, with the first element (array[0][0][0]) starting at the base address (&array), this works.
Declaring a multi-dimensional array dynamically is going to be a pointer to an array of pointers to (etc) to pointers to an array of object_type. You can simplify that by using std::vector or std::array (if you know the size at compile time).
Not that these use pointers to iterate (at least not directly), but
Vector/Array
std::vector<std::vector<std::vector<int> > > array;
// or
//std::array<std::array<std::array<int, DEPTH>, COLS>, ROWS> array; // with some slight modifications
// fill in the vectors/arrays however you want
std::for_each(array.begin(), array.end(), [](const std::vector<std::vector<int> >& v)
{
std::for_each(v.begin(), v.end(), [](const std::vector<int>& a)
{
std::for_each(a.begin(), a.end(), [](int i)
{
std::cout << i << endl;
});
});
});

all combinations of k elements out of n

Can somebody provide me a link or pseudocode of a function for finding all combinations of k elements out of n? possibly in STL. I don't need to compute n choose k, I need to list all vectors of numbers of size k.
Thanks
In C++ given the following routine:
template <typename Iterator>
inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Thomas Draper */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1,j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1,j,last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k,itr2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
You can then proceed to do the following:
// 9-choose-3
std::string s = "123456789";
std::size_t k = 3;
do
{
std::cout << std::string(s.begin(),s.begin() + k) << std::endl;
}
while(next_combination(s.begin(),s.begin() + k,s.end()));
Or for a std::vector of int's:
// 5-choose-3
std::size_t n = 5;
std::size_t k = 3;
std::vector<int> ints;
for (int i = 0; i < n; ints.push_back(i++));
do
{
for (int i = 0; i < k; ++i)
{
std::cout << ints[i];
}
std::cout << "\n";
}
while(next_combination(ints.begin(),ints.begin() + k,ints.end()));
http://howardhinnant.github.io/combinations.html
Search for "for_each_combination". If you find something faster, please let me know. Unlike other algorithms I often see, this one doesn't require the element type to be LessThanComparable.
Create an auxiliary vector with n - k zeros followed by k ones. A zero means the element in the original container is not included, whereas one means the element is included.
Now use std::next_permutation on the auxiliary vector to get the next combination.
Here is a lazy example of pseudocode that can get the job done...
void nChooseK(array[n],k){
recurse("",array[n],k);
}
void recurse(initialString,array[n],k){
if(k == 0){
print initialString;
return;
}
for(i=0;i<n;i++){
tmpArray = array[0...i-1]+array[i+1...];//the array without the object to remove
recurse(initialString + array[i], tmpArray,k-1)
}
}
You could use std::next_permutation but it is n! and not n choose k. You could filter them after you created them. But this solution is O(n!), not really perfect. Here is the trial and error solution:
int factorial(int value)
{
int result = 1;
for(int i = 1; i <= value; i++)
{
result *= i;
}
return result;
}
std::set<std::set<int>> binomial_coefficient(std::vector<int> input, int k)
{
std::set<std::set<int>> solutions;
for(unsigned int i = 0; i < factorial(input.size()); i++)
{
std::next_permutation(input.begin(), input.end());
solutions.insert(std::set<int>(input.begin(), input.begin() + k));
}
return solutions;
}