I'm trying to double each number in 2D arrays. For example the values in array1 would become {2,4,6}{4,8,12}{6,12,18}. The problem is that my code doubles the only the first number. Can someone give me some direction on what to do?
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 3;
int doubleValues(int arr[][N])
{
for (int i = 0; i < N; i++)
{
arr[i][N] *= 2;
for (int j = 0; j < N; j++)
{
arr[N][j] *= 2;
return arr[i][j];
}
}
}
void showArray(int arr[][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cout << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int array1 [N][N] = {
{ 1, 2, 3 } ,
{ 2, 4, 6 } ,
{ 3, 6, 9 }
};
int array2 [N][N] = {
{ 3, 4, 5 } ,
{ 6, 8, 10 } ,
{ 9, 12, 15 }
};
cout << "The values for array1 doubled are: \n";
doubleValues(array1);
showArray(array1);
cout << "The values for array2 double are: \n";
doubleValues(array2);
showArray(array2);
system("pause");
}
You have a return arr[i][j] in the inner loop of your doubleValues function. After doubling the first element, your function returns without doing any more work.
The solution is to remove this return statement. (And change doubleValues to a void function, because it doesn't need to return a value.)
Also, your doubleValues function seems to be modifying the wrong elements anyway. Both your accesses to arr[i][N] and arr[N][j] access elements out of bounds of your declared array size. You should probably be modifying arr[i][j] within your loop.
If you can use std::array for this project (since you know the size of your array at compile time) , you can use the functions within the <algorithm> header to easily implement your doubleValues function and not worry about hand-writing the loops.
template<typename T, std::size_t size>
void doubleValues(std::array<T,size>& arr)
{
std::transform(std::begin(arr),std::end(arr),std::begin(arr), [](auto x) { return 2 * x; });
}
This method would require that you break your 2d-array structure down into a single dimension, which can be accomplished with relative ease. For example,
std::array<int,N*N> array1 = { 1, 2, 3, 2, 4, 6, 3, 6, 9 };
std::array<int,N*N> array2 = { 3, 4, 5, 6, 8, 10, 9, 12, 15}
In the case where the size of the arrays could change dynamically, you can swap out std::array for std::vector.
Related
So for example I have a 2D array A={{1,2,3}, {2,3},{5}}; and I want to get all the rows existing in the array A. I have the length of array stored in variable "lenA", here lenA=3. Also I have an Array B which has the length of each subarray in A. Say B={3,2,1} in this case. In reference to my example array A, how to I dynamically get 3 subarrays from one 2D array i.e. A?
So as a result I would have something like:
A1={1,2,3}
A2={2,3}
A3={5}
You can't dynamically generate new identifiers in C++. The closest you can get is using the preprocessor to generate your names, and by definition, that's done before compilation.
If you already have a fixed number of named array pointers, you could assign those dynamically. But any solution that must accept an arbitrary number of rows at runtime will require that you use something like an array index.
for (int i = 0; i < lenA; i++)
{
// Do something with the row at A[i]
}
Pseudo code
for i in 0 to lenA-1
for j in 0 to lenB[i]-1
A[i][j] whatever...
My try converting A(4x4) to triangle *a[4]:
#include <iostream>
#include <algorithm>
int main()
{
constexpr int lenA = 4;
double A[lenA][lenA]={{1,2,3,4}, {5,6, 7, 0}, {8, 9,0,0},{10,0,0,0}};
double *a[lenA];
int B[lenA] = {4, 3, 2, 1};
for (int i=0; i < lenA; i++)
{
a[i] = new double [ B[i] ];
std::copy_n(A[i], B[i], a[i]);
}
for (int i=0; i<lenA; i++) {
std::cout << "row " << i << ": ";
for (int j=0; j<B[i]; j++) {
std::cout << a[i][j] << ". ";
}
std::cout <<std::endl;
}
return 0;
}
result:
$ ./a.exe
row 0: 1. 2. 3. 4.
row 1: 5. 6. 7.
row 2: 8. 9.
row 3: 10.
you can find the verification of the below code at http://cpp.sh/57pi2
A1D represent the 1-Dimensional array which you was looking for,
#include <iostream>
int main()
{
const int lenA = 4;
double A2D[][lenA]={{1,2,3,4},{5,6,7},{8,9},{10}};
double *A1D;
int B[lenA] = {4,3,2,1};
int num_of_elements = 0;
for (int i=0; i < lenA; i++)
num_of_elements += B[i];
A1D = new double[num_of_elements] ;
for (int i=0, k=0; i<lenA; i++)
for (int j=0; j<B[i]; j++)
A1D[k++] = A2D[i][j];
for (int j=0; j<num_of_elements; j++)
std::cout << A1D[j] << std::endl;
}
std::ranges in C++20 or ranges library (C++14 compliant) does it in clean way:
double A[][4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 0},
{ 8, 9, 0, 0},
{10, 0, 0, 0}
};
for (auto x : std::ranges::views::join(A))
std::cout << x << '\n';
https://godbolt.org/z/hPP7e9
I'm having an issue in my program with my insertElement() function. What I had intended insertElement to do is to take the index from the prototype and move all the values to the right, including the value on that index, to the right ONCE. So, If I were to have my array {1, 2, 3, 4} and I wanted to insert the value "10" at the index "2", the resulting array would be {1, 2, 10, 3, 4}.
I know I'd have to tweak my insertElement() function to fix this issue, but I'm not sure where to start, could anybody give me a hand? Here is my code:
#include <iostream>
using namespace std;
const int CAPACITY = 20;
void displayArray(int array[], int numElements)
{
for (int i = 0; i < numElements; i++)
cout << array[i] << " ";
cout << endl;
}
bool insertElement(int array[], int& numberElements, int insertPosition, int insertTarget)
{
int p = 0;
int j = 1;
int arrayPositionFromLast = (numberElements-1);
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
for (int i=arrayPositionFromLast; i>insertPosition; i--)
{
array[arrayPositionFromLast-p]=array[arrayPositionFromLast-j];
p++;
j++;
}
array[insertPosition] = insertTarget;
}
return true;
}
int main()
{
int array[6] = {1, 2, 3, 4, 5, 6};
int numArrayElements = 6;
int endOfArrayValue, insertedValue, insertedValuePosition;
cout << "Enter a value and a position to insert: ";
cin >> insertedValue >> insertedValuePosition;
insertElement(array, numArrayElements, insertedValuePosition, insertedValue);
displayArray(array, numArrayElements);
}
first you should define your array with CAPACITY
int array[CAPACITY] = {1, 2, 3, 4, 5, 6};
You can move your data with memmove.
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
memmove(array + insertPosition+ 1, array + insertPosition, (numberElements - insertPosition) * sizeof (int));
array[insertPosition] = insertTarget;
}
I'm trying to write a code where there is a research of even numbers and then it deletes the even numbers and then shifts all the other elements.
i is for offset and are the actual position of the elements in the array.
k is the position of the even number in the array.
int k;
for(i=0; i < N; i++)
{
if(Array[i] % 2 == 0)
{
for(k=i+1; k < N; k++)
{
Array[k-1] = Array[k];
}
N--;
}
}
Array=[2,10,3,5,8,7,3,3,7,10] the even numbers should be removed, but a 10
stays in the Array=[10,3,5,7,3,3,7].
Now is more than 3 hours that I'm trying to figure out what's wrong in my code.
This appears to be some sort of homework or school assignment. So what's the actual problem with the posted code?
It is that when you remove an even number at index i, you put the number that used to be at index i + 1 down into index i. Then you continue the outer loop iteration, which will check index i + 1, which is the number that was at the original i + 2 position in the array. So the number that started out at Array[i + 1], and is now in Array[i], is never checked.
A simple way to fix this is to decrement i when you decrement N.
Though already answered, I fail to see the reason people are driving this through a double for-loop, repetitively moving data over and over, with each reduction.
I completely concur with all the advice about using containers. Further, the algorithms solution doesn't require a container (you can use it on a native array), but containers still make it easier and cleaner. That said...
I described this algorithm in general-comment above. you don't need nested loops fr this. You need a read pointer and a write pointer. that's it.
#include <iostream>
size_t remove_even(int *arr, size_t n)
{
int *rptr = arr, *wptr = arr;
while (n-- > 0)
{
if (*rptr % 2 != 0)
*wptr++ = *rptr;
++rptr;
}
return (wptr - arr);
}
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
size_t n = remove_even(arr, sizeof arr / sizeof *arr);
for (size_t i=0; i<n; ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Output
3 5 7 3 3 7
If you think it doesn't make a difference, I invite you to fill an array with a million random integers, then try both solutions (the nested-for-loop approach vs. what you see above).
Using std::remove_if on a native array.
Provided only for clarity, the code above basically does what the standard algorithm std::remove_if does. All we need do is provide iterators (the array offsets and size will work nicely), and know how to interpret the results.
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
auto it = std::remove_if(std::begin(arr), std::end(arr),
[](int x){ return x%2 == 0; });
for (size_t i=0; i<(it - arr); ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Same results.
The idiomatic solution in C++ would be to use a STL algorithm.
This example use a C-style array.
int Array[100] = {2,10,3,5,8,7,3,3,7,10};
int N = 10;
// our remove_if predicate
auto removeEvenExceptFirst10 = [first10 = true](int const& num) mutable {
if (num == 10 && first10) {
first10 = false;
return false;
}
return num % 2 == 0;
};
auto newN = std::remove_if(
std::begin(Array), std::begin(Array) + N,
removeEvenExceptFirst10
);
N = std::distance(std::begin(Array), newN);
Live demo
You could use a std::vector and the standard function std::erase_if + the vectors erase function to do this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> Array = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
auto it = std::remove_if(
Array.begin(),
Array.end(),
[](int x) { return (x & 1) == 0 && x != 10; }
);
Array.erase(it, Array.end());
for(int x : Array) {
std::cout << x << "\n";
}
}
Output:
10
3
5
7
3
3
7
10
Edit: Doing it the hard way:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
for(size_t i = 0; i < N;) {
if((Array[i] & 1) == 0 && Array[i] != 10) {
for(size_t k = i + 1; k < N; ++k) {
Array[k - 1] = Array[k];
}
--N;
} else
++i; // only step i if you didn't shift the other values down
}
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Or simpler:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
size_t k = 0;
for(size_t i = 0; i < N; ++i) {
if((Array[i] & 1) || Array[i] == 10) {
// step k after having saved this value
Array[k++] = Array[i];
}
}
N = k;
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Is it possible to sort a 2D Array using qsort or std::sort in C++ such that the elements are in increasing order when read from left to right in each row or from top to bottom in each column?
For example,
13, 14, 15, 16
1, 4, 3, 2
7, 5, 7, 6
9, 10, 11, 12
Becomes:
{ 1, 2, 3, 4 }
{ 5, 6, 7, 8 }
{ 9, 10, 11, 12 }
{ 13, 14, 15, 16 }
I know you can do it by creating two comparison functions and then first sorting each row then comparing the first elements of each row to establish the columns, but is there a way to do it in one function itself?
# include <iostream>
using namespace std ;
void swap (int &x , int &y)
{
int temp = x ;
x = y ;
y = temp ;
}
void main ()
{
int arr [3][3] = {{90,80,70},{60,50,40},{30,100,10}} ;
int x ;
for (int k = 0; k < 3; k++)
{
for (int m = 0; m < 3; m++)
{
x = m+1;
for (int i = k; i < 3 ; i++)
{
for (int j = x; j < 3; j++)
{
if (arr [k][m] > arr [i][j])
swap(arr [k][m] ,arr [i][j]);
}
x=0;
}
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << arr [i][j] << " ";
}
}
system("pause");
}
C++ Sorting 2-D array ascendingly
Yes. C++ STL library is built with separation of algorithms and containers. What links them together is iterators. Raw pointer is iterator, therefore it is possible to initialize vector with raw pointers and then sort that vector as usual.
std::vector<int> v(arr2d, arr2d + N); // create a vector based on pointers
// This assumes array is contiguous range
// in memory, N=number of elemnts in arr2d
// using default comparison (operator <):
std::sort (v.begin(), v.end());
// cout by 4 elements in a row
In theory you should be able to input the 16 numbers into an array. Use a for loop, maybe even a nested one, to sort the numbers. Then as for output you want the ascending numbers in four groups of four?
cout<<Vector[0]<<Vector[1]<<Vector[2]<<Vector[3]<<endl;
cout<<Vector[4]<<Vector[5]<<Vector[6]<<Vector[7]<<endl;
cout<<Vector[8]<<Vector[9]<<Vector[10]<<Vector[11]<<endl;
cout<<Vector[12]<<Vector[13]<<Vector[14]<<Vector[15]<<endl;
very arbitrary but I'm not quite sure of the question.
First Make a 2D vector .
Sort each vector in this 2D vector
Sort the whole vector
Code :
#include <iostream>
#include <vector>
#include <algorithm>
template <class T>
void Sort2dArray(std::vector<std::vector<T>> & numbers)
{
for(auto & i : numbers){//sort each vector<T> in numbers
std::sort(i.begin(),i.end());
}
std::sort(numbers.begin(),numbers.end(),[](//sort numbers by defining custom compare
const std::vector<T>& a,const std::vector<T>&b){
for(int i=0;i<a.size()&&i<b.size();i++)
{
if(a[i]>b[i])
return false;
else if(a[i]<b[i])
return true;
}
return a.size()<b.size() ? true : false;
});
}
int main()
{
std::vector<std::vector<int>> numbers={ {13, 14, 15, 16},
{1, 4, 3, 2},
{8, 5, 7, 6},
{9, 10, 12,11}};
Sort2dArray(numbers);//sort array
//write sorted array
for(auto i:numbers)
{
for(auto j:i)
std::cout<<j<<" ";
std::cout<<"\n";
}
}
**Sorting 2D array in c++**
#include <iostream>
using namespace std;
int main()
{
int i,j,k,m,temp,n,limit;
int** p;
cout<<"Enter the limit:";
cin>>limit;
p=new int*[limit];
//inputing
for(i=0;i<limit;i++)
{
p[i] = new int[limit];
for(j=0;j<limit;j++)
{
cin>>p[i][j];
}
}
//sorting
for(i=0;i<limit;i++)
{
for(j=0;j<limit;j++)
{
if (j==limit-1 && i<limit-1)
{
n =-1;
m=i+1;
}
else
{
m=i;
n=j;
}
for(k=n+1;k<limit;k++)
{
if(p[i][j] > p[m][k] )
{
temp = p[i][j];
p[i][j] = p[m][k];
p[m][k] = temp;
}
if(k==limit-1 && m<limit-1) { m++; k=-1; }
}
}
}
//displaying
for(i=0;i<limit;i++)
{
for(j=0;j<limit;j++)
{
cout<<p[i][j]<<endl;
}
}
return 0;
}
I attempted a program to return an array with the indicies of the array where a specific inputed value is found, but every run results in an error, which seems to be an infinite run time. The error seems to be occuring right after printing out the last of the indicies found.
Can anyone help?
(Side note: I've seen multiple pages about deleting pointers when done with them; should I be doing that here?)
Forgot to mention - I want the first slot of the returned array to save the size of the array, so that it can be accessed easily later on in the program
#include <iostream>
#include <vector>
using namespace std;
int* linearSearch(int* n, int k, int f) {
// Input: Index 0 Address ; Size of Array; Element to Search
// Output: Array of Found Indicies
vector <int> a;
int* b;
for(int i = 0; i < k; i++)
if(n[i] == f)
a.push_back(i);
*b = a.size();
for(int i = 0; i < a.size(); i++)
b[i + 1] = a[i];
return b;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
int* k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k[0]; i++) {
cout << "Found at index: " << k[i + 1] << endl;
}
return 0;
}
int* b;
....
*b = a.size();
b has to be allocated. Try following:
int* b = new int[a.size() + 1];
b[0] = a.size();
I see what you meant. b will have magically length in first element. This was in Pascal/Delphi but not the case in C/C++.
You are writing to heap memory that you never claimed.
int* b;
This pointer, having never been initialized, points to an undefined memory address. Then when you use the indexing operator to assign your matches, you are writing to the subsequent bytes following the undefined memory address.
You need to allocate space for storing the results using the 'new[]' operator. Additionally, if you had correctly claimed the memory, you would be assigning the number of match results to the first element in the result array - something that doesn't seem to be your intention.
Take a look at dynamic memory allocation in C++ using the new [] operator.
If you use std::vector anyway, why not to use it where it is needed the most? Also if you not suppose to modify array by that pointer express that by const pointer:
std::vector<int> linearSearch(const int* n, int k, int f)
{
std::vector<int> res;
for(int i = 0; i < k; i++)
if(n[i] == f) res.push_back(i);
return res;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k.size(); i++) {
cout << "Found at index: " << k[i] << endl;
}
return 0;
}
This is not perfect but this is much closer to a correct implementation and you should be able to take it further with some work:
#include <iostream>
#include <vector>
using namespace std;
std::vector<int> linearSearch(int* n, int k, int f)
{
vector <int> a;
for(int i = 0; i < k; i++)
{
if(n[i] == f)
{
a.push_back(i);
}
}
return a ;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> result = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(unsigned int i = 0; i < result.size(); i++)
{
cout << "Found at index: " << result[i + 1] << endl;
}
return 0;
}