Is there a way to take two int arrays in C++
int * arr1;
int * arr2;
//pretend that in the lines below, we fill these two arrays with different
//int values
and then combine them into one larger array that contains both arrays' values?
Use std::copy defined in the header <algorithm>. The args are a pointer to the first element of the input, a pointer to one past the last element of the input, and a pointer to the first element of the output.
( https://en.cppreference.com/w/cpp/algorithm/copy )
int * result = new int[size1 + size2];
std::copy(arr1, arr1 + size1, result);
std::copy(arr2, arr2 + size2, result + size1);
Just suggestion, vector will do better as a dynamic array rather than pointer
If you're using arrays, you need to allocate a new array large enough to store all of the values, then copy the values into the arrays. This would require knowing the array sizes, etc.
If you use std::vector instead of arrays (which has other benefits), this becomes simpler:
std::vector<int> results;
results.reserve(arr1.size() + arr2.size());
results.insert(results.end(), arr1.begin(), arr1.end());
results.insert(results.end(), arr2.begin(), arr2.end());
Another alternative is to use expression templates and pretend the two are concatenated (lazy evaluation). Some links (you can do additional googling):
http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/
http://www.altdevblogaday.com/2012/01/23/abusing-c-with-expression-templates/
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s06.html
If you are looking for ease of use, try:
#include <iostream>
#include <string>
int main()
{
int arr1[] = {1, 2, 3};
int arr2[] = {3, 4, 6};
std::basic_string<int> s1(arr1, 3);
std::basic_string<int> s2(arr2, 3);
std::basic_string<int> concat(s1 + s2);
for (std::basic_string<int>::const_iterator i(concat.begin());
i != concat.end();
++i)
{
std::cout << *i << " ";
}
std::cout << std::endl;
return 0;
}
Here is the solution for the same-
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
void Concatenate(char *s1,char *s2)
{
char s[200];
int len1=strlen(s1);
int len2=strlen(s2);
int j;
///Define k to store the values on Kth address Kstart from 0 to len1+len2;
int k=0;
for(j=0;j<len1;j++)
{
s[k]=s1[j];
k++;
}
for(j=0;j<len2;j++)
{
s[k]=s2[j];
k++;
}
///To place a null at the last of the concatenated string to prevent Printing Garbage value;
s[k]='\n';
cout<<s;
}
int main()
{
char s1[100];
char s2[100];
cin.getline(s1,100);
cin.getline(s2,100);
Concatenate(s1,s2);
return 0;
}
Hope it helps.
for (int i = 0; i< arraySize * 2; i++)
{
if (i < aSize)
{
*(array3 + i) = *(array1 + i);
}
else if (i >= arraySize)
{
*(array3 + i) = *(array2 + (i - arraySize));
}
}
This might help you along, it doesn't require vectors. I had a similar problem in my programming class. I hope this helps, it was required that I used pointer arithmetic. This assumes that array1 and array2 are initialized dynamically to the size "aSize"
Given int * arr1 and int * arr2, this program Concatenates in int * arr3 the elements of the both arrays. Unfortunately, in C++ you need to know the sizes of each arrays you want to copy. But this is no impediment to choose how many elements you want to copy from arr1 and how many from arr2.
#include <iostream>
using namespace std;
int main(){
int temp[] = {1,2,3,4};
int temp2[] = {33,55,22};
int * arr1, * arr2, *arr3;
int size1(4), size2(3); //size1 and size2 is how many elements you
//want to copy from the first and second array. In our case all.
//arr1 = new int[size1]; // optional
//arr2 = new int[size2];
arr1=temp;
arr2=temp2;
arr3 = new int;
//or if you know the size: arr3 = new int[size1+size2];
for(int i=0; i<size1+size2; i++){
if (i<size1)
arr3[i]=arr1[i];
else
arr3[i] = arr2[i-size1];
}
cout<<endl;
for (int i=0; i<size1+size2; i++) {
cout<<arr3[i]<<", ";
}
}
I have an array of integers with a bunch of numbers from 1-10
Then I have an array of names(strings) which belong with the numbers a.e.
Numbers[0] = 5, Numbers[1] = 2
Names[0] = "Jeremy", Names [1] = "Samantha".
I can easily order the numbers with:
int n = sizeof(Numbers) / sizeof(Numbers[0]);
sort(Numbers, Numbers + n, greater<int>());
But then the names and numbers don't match at all.
How do I fix this?
A very common approach is to create an array of indices and sort that:
std::vector<int> indices(Numbers.size());
std::iota(indices.begin(), indices.end(), 0);
std::sort(indices.begin(), indices.end(),
[&](int A, int B) -> bool {
return Numbers[A] < Numbers[B];
});
The original arrays are not altered, but now indices can be used to access both arrays in the desired order.
If we want to reorder Numbers or Names in place, then we can
create a set of "back indices" that record where to find the element i in the sorted array:
std::vector<int> back_indices(indices.size());
for (size_t i = 0; i < indices.size(); i++)
back_indices[indices[i]] = i;
Now we can reorder, for example, Names in place in the desired order:
int index = 0;
std::string name = Names[index];
for (int i = 0; i < back_indices.size(); i++) {
index = back_indices[index];
std::swap(name,Names[index]);
}
I've tested this code which should give you the required behavior:
struct numberName {
int num;
string name;
};
bool compare(numberName a, numberName b){
return a.num < b.num; // if equal, no need to sort.
}
int main() {
numberName list[2];
list[0].num = 5, list[1].num = 2;
list[0].name = "Jeremy", list[1].name = "Samantha";
sort(list, list+2, compare);
}
Like HAL9000 said, you want to use a struct since this keeps variables that belong to each other together. Alternatively you could use a pair, but I don't know if a pair would be good practice for your situation or not.
This is a great example of the complexities introduced by using parallel arrays.
If you insist on keeping them as parallel arrays, here is a possible approach. Create a vector of integer indexes, initialised to { 0, 1, 2, 3, etc }. Each integer represents one position in your array. Sort your vector of indexes using a custom comparision function that uses the indexes to refer to array1 (Numbers). When finished you can use the sorted indexes to reorder array1 and array2 (Names).
One could also write their own sort algorithm that performs swaps on the extra array at the same time.
Or one could trick std::sort into sorting both arrays simultaneously by using a cleverly designed proxy. I will demonstrate that such a thing is possible, although the code below may be considered a simple hackish proof of concept.
Tricking std::sort with a cleverly-designed proxy
#include <iostream>
#include <algorithm>
constexpr size_t SZ = 2;
int Numbers[SZ] = {5, 2};
std::string Names[SZ] = {"Jeremy", "Samantha"};
int tempNumber;
std::string tempName;
class aproxy {
public:
const size_t index = 0;
const bool isTemp = false;
aproxy(size_t i) : index(i) {}
aproxy() = delete;
aproxy(const aproxy& b) : isTemp(true)
{
tempName = Names[b.index];
tempNumber = Numbers[b.index];
}
void operator=(const aproxy& b) {
if(b.isTemp) {
Names[index] = tempName;
Numbers[index] = tempNumber;
} else {
Names[index] = Names[b.index];
Numbers[index] = Numbers[b.index];
}
}
bool operator<(const aproxy& other) {
return Numbers[index] < Numbers[other.index];
}
};
int main() {
aproxy toSort[SZ] = {0, 1};
std::sort(toSort, toSort+SZ);
for(int i=0; i<SZ; ++i) {
std::cout << "Numbers[" << i << "]=" << Numbers[i] << std::endl;
std::cout << "Names[" << i << "]=" << Names[i] << std::endl;
}
return 0;
}
...and an even more cleverly-designed proxy could avoid entirely the need to allocate SZ "aproxy" elements.
Tricking std::sort with an "even more cleverly-designed" proxy
#include <iostream>
#include <algorithm>
class aproxy;
constexpr size_t SZ = 2;
int Numbers[SZ] = {5, 2};
std::string Names[SZ] = {"Jeremy", "Samantha"};
aproxy *tempProxyPtr = nullptr;
int tempNumber;
std::string tempName;
class aproxy {
public:
size_t index() const
{
return (this - reinterpret_cast<aproxy*>(Numbers));
}
bool isTemp() const
{
return (this == tempProxyPtr);
}
~aproxy()
{
if(isTemp()) tempProxyPtr = nullptr;
}
aproxy() {}
aproxy(const aproxy& b)
{
tempProxyPtr = this;
tempName = Names[b.index()];
tempNumber = Numbers[b.index()];
}
void operator=(const aproxy& b) {
if(b.isTemp()) {
Names[index()] = tempName;
Numbers[index()] = tempNumber;
} else {
Names[index()] = Names[b.index()];
Numbers[index()] = Numbers[b.index()];
}
}
bool operator<(const aproxy& other) {
return Numbers[index()] < Numbers[other.index()];
}
};
int main() {
aproxy* toSort = reinterpret_cast<aproxy*>(Numbers);
std::sort(toSort, toSort+SZ);
for(int i=0; i<SZ; ++i) {
std::cout << "Numbers[" << i << "]=" << Numbers[i] << std::endl;
std::cout << "Names[" << i << "]=" << Names[i] << std::endl;
}
return 0;
}
Disclaimer: although my final example above may technically be in violation of the strict-aliasing rule (due to accessing the same space in memory as two different types), the underlying memory is only used for addressing space-- not modified-- and it does seems to work fine when I tested it. Also it relies entirely on std::sort being written in a certain way: using a single temp variable initialized via copy construction, single-threaded, etc. Putting together all these assumptions it may be a convenient trick but not very portable so use at your own risk.
I have a function which I want to take, as a parameter, a 2D array of variable size.
So far I have this:
void myFunction(double** myArray){
myArray[x][y] = 5;
etc...
}
And I have declared an array elsewhere in my code:
double anArray[10][10];
However, calling myFunction(anArray) gives me an error.
I do not want to copy the array when I pass it in. Any changes made in myFunction should alter the state of anArray. If I understand correctly, I only want to pass in as an argument a pointer to a 2D array. The function needs to accept arrays of different sizes also. So for example, [10][10] and [5][5]. How can I do this?
There are three ways to pass a 2D array to a function:
The parameter is a 2D array
int array[10][10];
void passFunc(int a[][10])
{
// ...
}
passFunc(array);
The parameter is an array containing pointers
int *array[10];
for(int i = 0; i < 10; i++)
array[i] = new int[10];
void passFunc(int *a[10]) //Array containing pointers
{
// ...
}
passFunc(array);
The parameter is a pointer to a pointer
int **array;
array = new int *[10];
for(int i = 0; i <10; i++)
array[i] = new int[10];
void passFunc(int **a)
{
// ...
}
passFunc(array);
Fixed Size
1. Pass by reference
template <size_t rows, size_t cols>
void process_2d_array_template(int (&array)[rows][cols])
{
std::cout << __func__ << std::endl;
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
In C++ passing the array by reference without losing the dimension information is probably the safest, since one needn't worry about the caller passing an incorrect dimension (compiler flags when mismatching). However, this isn't possible with dynamic (freestore) arrays; it works for automatic (usually stack-living) arrays only i.e. the dimensionality should be known at compile time.
2. Pass by pointer
void process_2d_array_pointer(int (*array)[5][10])
{
std::cout << __func__ << std::endl;
for (size_t i = 0; i < 5; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < 10; ++j)
std::cout << (*array)[i][j] << '\t';
std::cout << std::endl;
}
}
The C equivalent of the previous method is passing the array by pointer. This should not be confused with passing by the array's decayed pointer type (3), which is the common, popular method, albeit less safe than this one but more flexible. Like (1), use this method when all the dimensions of the array is fixed and known at compile-time. Note that when calling the function the array's address should be passed process_2d_array_pointer(&a) and not the address of the first element by decay process_2d_array_pointer(a).
Variable Size
These are inherited from C but are less safe, the compiler has no way of checking, guaranteeing that the caller is passing the required dimensions. The function only banks on what the caller passes in as the dimension(s). These are more flexible than the above ones since arrays of different lengths can be passed to them invariably.
It is to be remembered that there's no such thing as passing an array directly to a function in C [while in C++ they can be passed as a reference (1)]; (2) is passing a pointer to the array and not the array itself. Always passing an array as-is becomes a pointer-copy operation which is facilitated by array's nature of decaying into a pointer.
3. Pass by (value) a pointer to the decayed type
// int array[][10] is just fancy notation for the same thing
void process_2d_array(int (*array)[10], size_t rows)
{
std::cout << __func__ << std::endl;
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < 10; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
Although int array[][10] is allowed, I'd not recommend it over the above syntax since the above syntax makes it clear that the identifier array is a single pointer to an array of 10 integers, while this syntax looks like it's a 2D array but is the same pointer to an array of 10 integers. Here we know the number of elements in a single row (i.e. the column size, 10 here) but the number of rows is unknown and hence to be passed as an argument. In this case there's some safety since the compiler can flag when a pointer to an array with second dimension not equal to 10 is passed. The first dimension is the varying part and can be omitted. See here for the rationale on why only the first dimension is allowed to be omitted.
4. Pass by pointer to a pointer
// int *array[10] is just fancy notation for the same thing
void process_pointer_2_pointer(int **array, size_t rows, size_t cols)
{
std::cout << __func__ << std::endl;
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
Again there's an alternative syntax of int *array[10] which is the same as int **array. In this syntax the [10] is ignored as it decays into a pointer thereby becoming int **array. Perhaps it is just a cue to the caller that the passed array should have at least 10 columns, even then row count is required. In any case the compiler doesn't flag for any length/size violations (it only checks if the type passed is a pointer to pointer), hence requiring both row and column counts as parameter makes sense here.
Note: (4) is the least safest option since it hardly has any type check and the most inconvenient. One cannot legitimately pass a 2D array to this function; C-FAQ condemns the usual workaround of doing int x[5][10]; process_pointer_2_pointer((int**)&x[0][0], 5, 10); as it may potentially lead to undefined behaviour due to array flattening. The right way of passing an array in this method brings us to the inconvenient part i.e. we need an additional (surrogate) array of pointers with each of its element pointing to the respective row of the actual, to-be-passed array; this surrogate is then passed to the function (see below); all this for getting the same job done as the above methods which are more safer, cleaner and perhaps faster.
Here's a driver program to test the above functions:
#include <iostream>
// copy above functions here
int main()
{
int a[5][10] = { { } };
process_2d_array_template(a);
process_2d_array_pointer(&a); // <-- notice the unusual usage of addressof (&) operator on an array
process_2d_array(a, 5);
// works since a's first dimension decays into a pointer thereby becoming int (*)[10]
int *b[5]; // surrogate
for (size_t i = 0; i < 5; ++i)
{
b[i] = a[i];
}
// another popular way to define b: here the 2D arrays dims may be non-const, runtime var
// int **b = new int*[5];
// for (size_t i = 0; i < 5; ++i) b[i] = new int[10];
process_pointer_2_pointer(b, 5, 10);
// process_2d_array(b, 5);
// doesn't work since b's first dimension decays into a pointer thereby becoming int**
}
A modification to shengy's first suggestion, you can use templates to make the function accept a multi-dimensional array variable (instead of storing an array of pointers that have to be managed and deleted):
template <size_t size_x, size_t size_y>
void func(double (&arr)[size_x][size_y])
{
printf("%p\n", &arr);
}
int main()
{
double a1[10][10];
double a2[5][5];
printf("%p\n%p\n\n", &a1, &a2);
func(a1);
func(a2);
return 0;
}
The print statements are there to show that the arrays are getting passed by reference (by displaying the variables' addresses)
Surprised that no one mentioned this yet, but you can simply template on anything 2D supporting [][] semantics.
template <typename TwoD>
void myFunction(TwoD& myArray){
myArray[x][y] = 5;
etc...
}
// call with
double anArray[10][10];
myFunction(anArray);
It works with any 2D "array-like" datastructure, such as std::vector<std::vector<T>>, or a user defined type to maximize code reuse.
You can create a function template like this:
template<int R, int C>
void myFunction(double (&myArray)[R][C])
{
myArray[x][y] = 5;
etc...
}
Then you have both dimension sizes via R and C. A different function will be created for each array size, so if your function is large and you call it with a variety of different array sizes, this may be costly. You could use it as a wrapper over a function like this though:
void myFunction(double * arr, int R, int C)
{
arr[x * C + y] = 5;
etc...
}
It treats the array as one dimensional, and uses arithmetic to figure out the offsets of the indexes. In this case, you would define the template like this:
template<int C, int R>
void myFunction(double (&myArray)[R][C])
{
myFunction(*myArray, R, C);
}
anArray[10][10] is not a pointer to a pointer, it is a contiguous chunk of memory suitable for storing 100 values of type double, which compiler knows how to address because you specified the dimensions. You need to pass it to a function as an array. You can omit the size of the initial dimension, as follows:
void f(double p[][10]) {
}
However, this will not let you pass arrays with the last dimension other than ten.
The best solution in C++ is to use std::vector<std::vector<double> >: it is nearly as efficient, and significantly more convenient.
Here is a vector of vectors matrix example
#include <iostream>
#include <vector>
using namespace std;
typedef vector< vector<int> > Matrix;
void print(Matrix& m)
{
int M=m.size();
int N=m[0].size();
for(int i=0; i<M; i++) {
for(int j=0; j<N; j++)
cout << m[i][j] << " ";
cout << endl;
}
cout << endl;
}
int main()
{
Matrix m = { {1,2,3,4},
{5,6,7,8},
{9,1,2,3} };
print(m);
//To initialize a 3 x 4 matrix with 0:
Matrix n( 3,vector<int>(4,0));
print(n);
return 0;
}
output:
1 2 3 4
5 6 7 8
9 1 2 3
0 0 0 0
0 0 0 0
0 0 0 0
Single dimensional array decays to a pointer pointer pointing to the first element in the array. While a 2D array decays to a pointer pointing to first row. So, the function prototype should be -
void myFunction(double (*myArray) [10]);
I would prefer std::vector over raw arrays.
We can use several ways to pass a 2D array to a function:
Using single pointer we have to typecast the 2D array.
#include<bits/stdc++.h>
using namespace std;
void func(int *arr, int m, int n)
{
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
cout<<*((arr+i*n) + j)<<" ";
}
cout<<endl;
}
}
int main()
{
int m = 3, n = 3;
int arr[m][n] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
func((int *)arr, m, n);
return 0;
}
Using double pointer In this way, we also typecast the 2d array
#include<bits/stdc++.h>
using namespace std;
void func(int **arr, int row, int col)
{
for (int i=0; i<row; i++)
{
for(int j=0 ; j<col; j++)
{
cout<<arr[i][j]<<" ";
}
printf("\n");
}
}
int main()
{
int row, colum;
cin>>row>>colum;
int** arr = new int*[row];
for(int i=0; i<row; i++)
{
arr[i] = new int[colum];
}
for(int i=0; i<row; i++)
{
for(int j=0; j<colum; j++)
{
cin>>arr[i][j];
}
}
func(arr, row, colum);
return 0;
}
You can do something like this...
#include<iostream>
using namespace std;
//for changing values in 2D array
void myFunc(double *a,int rows,int cols){
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
*(a+ i*rows + j)+=10.0;
}
}
}
//for printing 2D array,similar to myFunc
void printArray(double *a,int rows,int cols){
cout<<"Printing your array...\n";
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
cout<<*(a+ i*rows + j)<<" ";
}
cout<<"\n";
}
}
int main(){
//declare and initialize your array
double a[2][2]={{1.5 , 2.5},{3.5 , 4.5}};
//the 1st argument is the address of the first row i.e
//the first 1D array
//the 2nd argument is the no of rows of your array
//the 3rd argument is the no of columns of your array
myFunc(a[0],2,2);
//same way as myFunc
printArray(a[0],2,2);
return 0;
}
Your output will be as follows...
11.5 12.5
13.5 14.5
One important thing for passing multidimensional arrays is:
First array dimension need not be specified.
Second(any any further)dimension must be specified.
1.When only second dimension is available globally (either as a macro or as a global constant)
const int N = 3;
void print(int arr[][N], int m)
{
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < N; j++)
printf("%d ", arr[i][j]);
}
int main()
{
int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
print(arr, 3);
return 0;
}
2.Using a single pointer:
In this method,we must typecast the 2D array when passing to function.
void print(int *arr, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d ", *((arr+i*n) + j));
}
int main()
{
int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int m = 3, n = 3;
// We can also use "print(&arr[0][0], m, n);"
print((int *)arr, m, n);
return 0;
}
#include <iostream>
/**
* Prints out the elements of a 2D array row by row.
*
* #param arr The 2D array whose elements will be printed.
*/
template <typename T, size_t rows, size_t cols>
void Print2DArray(T (&arr)[rows][cols]) {
std::cout << '\n';
for (size_t row = 0; row < rows; row++) {
for (size_t col = 0; col < cols; col++) {
std::cout << arr[row][col] << ' ';
}
std::cout << '\n';
}
}
int main()
{
int i[2][5] = { {0, 1, 2, 3, 4},
{5, 6, 7, 8, 9} };
char c[3][9] = { {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'},
{'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'},
{'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '&'} };
std::string s[4][4] = { {"Amelia", "Edward", "Israel", "Maddox"},
{"Brandi", "Fabian", "Jordan", "Norman"},
{"Carmen", "George", "Kelvin", "Oliver"},
{"Deanna", "Harvey", "Ludwig", "Philip"} };
Print2DArray(i);
Print2DArray(c);
Print2DArray(s);
std::cout <<'\n';
}
In the case you want to pass a dynamic sized 2-d array to a function, using some pointers could work for you.
void func1(int *arr, int n, int m){
...
int i_j_the_element = arr[i * m + j]; // use the idiom of i * m + j for arr[i][j]
...
}
void func2(){
...
int arr[n][m];
...
func1(&(arr[0][0]), n, m);
}
You can use template facility in C++ to do this. I did something like this :
template<typename T, size_t col>
T process(T a[][col], size_t row) {
...
}
the problem with this approach is that for every value of col which you provide, the a new function definition is instantiated using the template.
so,
int some_mat[3][3], another_mat[4,5];
process(some_mat, 3);
process(another_mat, 4);
instantiates the template twice to produce 2 function definitions (one where col = 3 and one where col = 5).
If you want to pass int a[2][3] to void func(int** pp) you need auxiliary steps as follows.
int a[2][3];
int* p[2] = {a[0],a[1]};
int** pp = p;
func(pp);
As the first [2] can be implicitly specified, it can be simplified further as.
int a[][3];
int* p[] = {a[0],a[1]};
int** pp = p;
func(pp);
You are allowed to omit the leftmost dimension and so you end up with two options:
void f1(double a[][2][3]) { ... }
void f2(double (*a)[2][3]) { ... }
double a[1][2][3];
f1(a); // ok
f2(a); // ok
This is the same with pointers:
// compilation error: cannot convert ‘double (*)[2][3]’ to ‘double***’
// double ***p1 = a;
// compilation error: cannot convert ‘double (*)[2][3]’ to ‘double (**)[3]’
// double (**p2)[3] = a;
double (*p3)[2][3] = a; // ok
// compilation error: array of pointers != pointer to array
// double *p4[2][3] = a;
double (*p5)[3] = a[0]; // ok
double *p6 = a[0][1]; // ok
The decay of an N dimensional array to a pointer to N-1 dimensional array is allowed by C++ standard, since you can lose the leftmost dimension and still being able to correctly access array elements with N-1 dimension information.
Details in here
Though, arrays and pointers are not the same: an array can decay into a pointer, but a pointer doesn't carry state about the size/configuration of the data to which it points.
A char ** is a pointer to a memory block containing character pointers, which themselves point to memory blocks of characters. A char [][] is a single memory block which contains characters. This has an impact on how the compiler translate the code and how the final performance will be.
Source
Despite appearances, the data structure implied by double** is fundamentally incompatible with that of a fixed c-array (double[][]).
The problem is that both are popular (although) misguided ways to deal with arrays in C (or C++).
See https://www.fftw.org/fftw3_doc/Dynamic-Arrays-in-C_002dThe-Wrong-Way.html
If you can't control either part of the code you need a translation layer (called adapt here), as explained here: https://c-faq.com/aryptr/dynmuldimary.html
You need to generate an auxiliary array of pointers, pointing to each row of the c-array.
#include<algorithm>
#include<cassert>
#include<vector>
void myFunction(double** myArray) {
myArray[2][3] = 5;
}
template<std::size_t N, std::size_t M>
auto adapt(double(&Carr2D)[N][M]) {
std::array<double*, N> ret;
std::transform(
std::begin(Carr2D), std::end(Carr2D),
ret.begin(),
[](auto&& row) { return &row[0];}
);
return ret;
}
int main() {
double anArray[10][10];
myFunction( adapt(anArray).data() );
assert(anArray[2][3] == 5);
}
(see working code here: https://godbolt.org/z/7M7KPzbWY)
If it looks like a recipe for disaster is because it is, as I said the two data structures are fundamentally incompatible.
If you can control both ends of the code, these days, you are better off using a modern (or semimodern) array library, like Boost.MultiArray, Boost.uBLAS, Eigen or Multi.
If the arrays are going to be small, you have "tiny" arrays libraries, for example inside Eigen or if you can't afford any dependency you might try simply with std::array<std::array<double, N>, M>.
With Multi, you can simply do this:
#include<multi/array.hpp>
#include<cassert>
namespace multi = boost::multi;
template<class Array2D>
void myFunction(Array2D&& myArray) {
myArray[2][3] = 5;
}
int main() {
multi::array<double, 2> anArray({10, 10});
myFunction(anArray);
assert(anArray[2][3] == 5);
}
(working code: https://godbolt.org/z/7M7KPzbWY)
You could take arrays of an arbitrary number of dimensions by reference and peel off one layer at a time recursively.
Here's an example of a print function for demonstrational purposes:
#include <cstddef>
#include <iostream>
#include <iterator>
#include <string>
#include <type_traits>
template <class T, std::size_t N>
void print(const T (&arr)[N], unsigned indent = 0) {
if constexpr (std::rank_v<T> == 0) {
// inner layer - print the values:
std::cout << std::string(indent, ' ') << '{';
auto it = std::begin(arr);
std::cout << *it;
for (++it; it != std::end(arr); ++it) {
std::cout << ", " << *it;
}
std::cout << '}';
} else {
// still more layers to peel off:
std::cout << std::string(indent, ' ') << "{\n";
auto it = std::begin(arr);
print(*it, indent + 1);
for (++it; it != std::end(arr); ++it) {
std::cout << ",\n";
print(*it, indent + 1);
}
std::cout << '\n' << std::string(indent, ' ') << '}';
}
}
Here's a usage example with a 3 dimensional array:
int main() {
int array[2][3][5]
{
{
{1, 2, 9, -5, 3},
{6, 7, 8, -45, -7},
{11, 12, 13, 14, 25}
},
{
{4, 5, 0, 33, 34},
{8, 9, 99, 54, 44},
{14, 15, 16, 19, 20}
}
};
print(array);
}
... which will produce this output:
{
{
{1, 2, 9, -5, 3},
{6, 7, 8, -45, -7},
{11, 12, 13, 14, 25}
},
{
{4, 5, 0, 33, 34},
{8, 9, 99, 54, 44},
{14, 15, 16, 19, 20}
}
}
Is there a way to take two int arrays in C++
int * arr1;
int * arr2;
//pretend that in the lines below, we fill these two arrays with different
//int values
and then combine them into one larger array that contains both arrays' values?
Use std::copy defined in the header <algorithm>. The args are a pointer to the first element of the input, a pointer to one past the last element of the input, and a pointer to the first element of the output.
( https://en.cppreference.com/w/cpp/algorithm/copy )
int * result = new int[size1 + size2];
std::copy(arr1, arr1 + size1, result);
std::copy(arr2, arr2 + size2, result + size1);
Just suggestion, vector will do better as a dynamic array rather than pointer
If you're using arrays, you need to allocate a new array large enough to store all of the values, then copy the values into the arrays. This would require knowing the array sizes, etc.
If you use std::vector instead of arrays (which has other benefits), this becomes simpler:
std::vector<int> results;
results.reserve(arr1.size() + arr2.size());
results.insert(results.end(), arr1.begin(), arr1.end());
results.insert(results.end(), arr2.begin(), arr2.end());
Another alternative is to use expression templates and pretend the two are concatenated (lazy evaluation). Some links (you can do additional googling):
http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/
http://www.altdevblogaday.com/2012/01/23/abusing-c-with-expression-templates/
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s06.html
If you are looking for ease of use, try:
#include <iostream>
#include <string>
int main()
{
int arr1[] = {1, 2, 3};
int arr2[] = {3, 4, 6};
std::basic_string<int> s1(arr1, 3);
std::basic_string<int> s2(arr2, 3);
std::basic_string<int> concat(s1 + s2);
for (std::basic_string<int>::const_iterator i(concat.begin());
i != concat.end();
++i)
{
std::cout << *i << " ";
}
std::cout << std::endl;
return 0;
}
Here is the solution for the same-
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
void Concatenate(char *s1,char *s2)
{
char s[200];
int len1=strlen(s1);
int len2=strlen(s2);
int j;
///Define k to store the values on Kth address Kstart from 0 to len1+len2;
int k=0;
for(j=0;j<len1;j++)
{
s[k]=s1[j];
k++;
}
for(j=0;j<len2;j++)
{
s[k]=s2[j];
k++;
}
///To place a null at the last of the concatenated string to prevent Printing Garbage value;
s[k]='\n';
cout<<s;
}
int main()
{
char s1[100];
char s2[100];
cin.getline(s1,100);
cin.getline(s2,100);
Concatenate(s1,s2);
return 0;
}
Hope it helps.
for (int i = 0; i< arraySize * 2; i++)
{
if (i < aSize)
{
*(array3 + i) = *(array1 + i);
}
else if (i >= arraySize)
{
*(array3 + i) = *(array2 + (i - arraySize));
}
}
This might help you along, it doesn't require vectors. I had a similar problem in my programming class. I hope this helps, it was required that I used pointer arithmetic. This assumes that array1 and array2 are initialized dynamically to the size "aSize"
Given int * arr1 and int * arr2, this program Concatenates in int * arr3 the elements of the both arrays. Unfortunately, in C++ you need to know the sizes of each arrays you want to copy. But this is no impediment to choose how many elements you want to copy from arr1 and how many from arr2.
#include <iostream>
using namespace std;
int main(){
int temp[] = {1,2,3,4};
int temp2[] = {33,55,22};
int * arr1, * arr2, *arr3;
int size1(4), size2(3); //size1 and size2 is how many elements you
//want to copy from the first and second array. In our case all.
//arr1 = new int[size1]; // optional
//arr2 = new int[size2];
arr1=temp;
arr2=temp2;
arr3 = new int;
//or if you know the size: arr3 = new int[size1+size2];
for(int i=0; i<size1+size2; i++){
if (i<size1)
arr3[i]=arr1[i];
else
arr3[i] = arr2[i-size1];
}
cout<<endl;
for (int i=0; i<size1+size2; i++) {
cout<<arr3[i]<<", ";
}
}
I've written a loop in C++ to give me 6 random numbers and store them in an array.
What I would like to do is to sum the elements of the array until I get a value larger than a number, "x", but I would like to do this without necessarily adding all the elements. The objective is to find the first elements which sum to the value of x.
For example, array is [1,2,3,4,5,6], and x = 6, so what I would be looking for are the elements [1,2,3].
I've looked at the standard library and have tried using the sum function from "valarray" but this just gives the sum of all the elements. Any ideas on how to code this successfully would be greatly appreciated.
Write a functor that does the addition.
#include <algorithm>
struct SumToo
{
SumToo(int val):m_val(val),m_sum(0) {}
int m_val;
int m_sum;
bool operator()(int next)
{
m_sum += next;
return m_sum >= m_val;
}
};
int main()
{
int data[] = {1,2,3,4,5,6};
int* find = std::find_if(data,data+6,SumToo(6));
}
I'm assuming you just want the first X elements in the array, up until their sum meets or exceeds a threshold (the question was a little vague there).
If so, I don't know how to do that without your own loop:
int sum = 0;
int i = 0;
for( ; i < len; ++i ) {
sum += array[i];
if( sum >= 6 ) {
break;
}
}
Now "i" contains the index at which the sum met or exceeded your threshold.
Avoid the answers that suggest using find_if with a stateful predicate. Stateful predicates are dangerous as the STL algorithms assume it is safe to copy predicates. In this case, if copies are made of the predicate then each will have a different 'running total' and will not necessarily act on all values, or in the correct order.
Especially avoid the solution that implements its predicate's operator() member as a const member function but labels its members as mutable as this is fooling you into thinking it is not a stateful predicate, which is bad.
I'd suggest using either one of the answers that simply loops to find the answer, or the answer that uses an accumulator, as that is the most correct way to do it (even if the code looks a little unwieldy.
Note that the warnings may well not apply to C arrays and find_if; I just don't want you to learn that stateful predicates are the right way to solve your problem since you may end up using that incorrect solution in a situation where it is dangerous in future.
Reference: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices, Item 87
Here's a slightly more generic version:
#include <iostream>
#include <algorithm>
// return an iterator _Last such that sum
// of all elements in the range [_First, _Last)
// satisfies the predicate Func
template<class InIt,
class Ty,
class Fn> inline
InIt accumulate_if(InIt First, InIt Last, Ty Val, Fn Func)
{
for (; Func(Val) && First != Last; ++First)
Val = Val + *First;
return (First);
}
int main() {
int num[] = {1, 2, 3, 4, 5, 6};
int *last = accumulate_if(num, num + sizeof num / sizeof num[ 0 ],
0, std::bind2nd(std::less<int>(), 6));
std::copy(num, last, std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
Substract the numbers from x one by one, until you reach 0 or lower.
No additions, as you wished :)
Here's hoping this works:
/* Returns an index i, given array valarray[0,1..n] and number x where i is an index to valarry such that sum over j of valarray[j] for j = 0 to i > x */
int getFirstSum(int *valarray, int n, int x)
{
int i = 0;
int sum = x;
while(sum > x && i < n)
{
i++;
sum -= valarray[i];
}
return i;
}
would be something like:
struct StopAtValue{
StopAtValue(int sum) : m_sum(sum), m_accumulated(0){}
bool operator()(int val){
m_accumulated += val;
return m_accumulated >= sum;
}
int m_sum;
int m_accumulated;
}
int* pos = std::find_if(&array[0], &array[n], StopAtValue(6));
Well, i would use a vector
T addUntil(T array[],size_t len,T thres){
vector<T> vec = vector_from_array(array,len)
T sum;
for (size_t i=0;i< vec.size(),sum<thresh;i++){
sum+= vec[i];
}
return sum;
}
T would need operator+ and operator< to be defined.
You could use std::find_if() along with a functor that maintains a running total, and only returtn true from the functor when you have found the element that puts you at or over the top.
For example:
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
using namespace std;
// functor returns true when the running total >= findVal
struct running_total : public unary_function<int, bool>
{
running_total(int findVal) : findVal_(findVal), runningTtl_(0) {};
bool operator()(int rhs) const
{
runningTtl_ += rhs;
if( runningTtl_ >= findVal_ )
return true;
else
return false;
}
private:
mutable int runningTtl_;
const int findVal_;
};
int main()
{
int nums[] = {1, 2, 3, 4, 5, 6};
size_t count = sizeof(nums)/sizeof(nums[0]);
const int scanTtl = 6; // running total to scan to
int * pos = find_if(&nums[0], &nums[0]+count, running_total(scanTtl));
cout << "Elements Totaling " << scanTtl << " : ";
copy(&nums[0], pos+1, ostream_iterator<int>(cout, ", "));
return 0;
}