I am having trouble figuring out how to shift the elements of an array to the right using pointers (and not using swap). I have tried to play around with where the pointer starts and how it increments but it always messes up the output of the array when I test it just by printing the array values. Please help I am so frustrated.
// REQUIRES: there are at least n elements in arr;
// n >= 1
// MODIFIES: the elements in arr
// EFFECTS: All elements are "shifted" right by one unit, with the
// last element wrapping around to the beginning.
// EXAMPLE: If arr contains [0,1,3,3,4], it would be modified to
// contain [4,0,1,3,3]
// NOTE: You must use traversal by pointer.
// You may not use an extra array.
void slideRight(int arr[], int n) {
int *temp = arr;
for(int *ptr = arr+1; ptr < arr + n - 1;) {
arr[*ptr] = arr[*ptr-1];
}
arr[0] = *temp;
}
Your code has several problems.
First, it contains an infinite loop:
ptr < arr + n - 1
is true for arrays of size larger than 1.
This is unchanged throughout the loop.
Only the contents of arr is changed.
Second, it has a potential out-of-bounds, accessing arr[*ptr],
since *ptr is some arbitrary integer stored in the array.
There is a standard algorithm that does exactly this operation:
void slideRight(int arr[], int n) {
std::rotate(arr, arr + n - 1, arr + n);
}
Related
I read how to pass 2-D arrays in a function as a parameter and tried to implement the same. There are two problems which I encountered:
1) The first line of the output of the code contains garbage value.
2) What does the line ((arr + in) + j) actually do ? I mean, Why can't we do something like ((arr + i) + j) to access arr[i][j] ?
I also tried passing the matrix using parameter int **arr and then tried printing the value as arr[i][j] but there was no output.
Here is the output that I get:-
Enter number of nodes: 4
0167772161878012032-1
0000
0000
0000
And here is my code :-
#include <iostream>
using namespace std;
void show(int* arr, int n)
{
int i, j;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
cout << *((arr + i*n) + j);
}
cout << endl;
}
}
int main()
{
int n, i, j;
cout << "Enter number of nodes: ";
cin >> n;
int arr[n][n] = {{0}}; //Will initialize all elements in the matrix with 0.
show((int*)arr, n);
}
The biggest problem here is that you are using C and not C++.
To avoid people gasping and starting religious or political discussion, let's nail it down to:
VLAs (Variable Length Arrays) are not allowed in C++.
Additionally, you should never use raw pointers for owned memory and no pinter arithmetic.
And then the main topic:
Issue in Passing a 2-D array
The used syntax for passing arrays to function is wrong. In C++ arrays can be passed by reference or by pointer. Please see:
void function1(int(&m)[3][4]) // For passing array by reference
{}
void function2(int(*m)[3][4]) // For passing array by pointer
{}
int main()
{
int matrix[3][4]; // Define 2 dimensional array
function1(matrix); // Call by reference
function2(&matrix); // Call via pointer
return 0;
}
Of course we can do all kind of dirty designs with pointers. Even accepting pointer decays. But we should not do it.
Variable length arrays is not a standard C++ feature.
Nevertheless you passed to the function a pointer to the first element of a two-dimensional array.
Each "row" of the two-dimensional array has n elements. So if you have a pointer to the first element of the first row then to get the pointer to the first element of the second row you have to write
arr + n
If you want to get the first pointer to the i-th row of the two-dimensional array you have to write
arr + i * n
To get pointer to an element within the row you have to write
( arr + i * n ) + j
that is the same as
arr + i ( n + j
to get the element pointed to by the pointer you have to dereference the pointer
*( arr + i * n + j )
I am trying out some codes that is based on finding all possible combinations that add up to a integer's value that is declared in the main function. However, the problem is when I call the function "findCombinations(n);", it gives an error at "int arr[n];". That is the only line which has an error which is stopping me from running the program. If you know of a solution, do let me know.
#include <iostream>
using namespace std;
void findCombinationsUtil(int arr[], int index,
int num, int reducedNum)
{
// Base condition
if (reducedNum < 0)
return;
// If combination is found, print it
if (reducedNum == 0)
{
for (int i = 0; i < index; i++)
cout << arr[i] << " ";
cout << endl;
return;
}
// Find the previous number stored in arr[]
// It helps in maintaining increasing order
int prev = (index == 0) ? 1 : arr[index - 1];
// note loop starts from previous number
// i.e. at array location index - 1
for (int k = prev; k <= num; k++)
{
// next element of array is k
arr[index] = k;
// call recursively with reduced number
findCombinationsUtil(arr, index + 1, num,
reducedNum - k);
}
}
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
int arr[n];
//find all combinations
findCombinationsUtil(arr, 0, n, n);
}
int main()
{
int n = 10;
findCombinations(n);
return 0;
}
C-style array dimensions must be known at compile-time in Standard C++.
You can make n be a compile-time function parameter like this:
template<int n>
void findCombinations()
{
// array to store the combinations
// It can contain max n elements
int arr[n];
//find all combinations
findCombinationsUtil(arr, 0, n, n);
}
int main()
{
const int n = 10;
findCombinations<n>();
return 0;
}
From http://www.cplusplus.com/doc/tutorial/arrays/:
NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.
While some compilers will allow it, you should avoid dynamic size arrays.
Here are a few options:
If the size of the array will always be 10, initiate it to hard-coded const 10.
Use std::shared_ptr to an array pointer:
std::shared_ptr pArray;
pArray=std::make_shared(n)
Use std::vector to dynamically allocate the size. (IMHO this is the preferred option).
use c-style pointers (IMHO should only be used as last resort)
Template class (wasteful, as it created and compiles many instances of the same function)
Type of variable arr must be known at compile time. If you need storage of variable size, you have to allocate it.
Possible alternative (one of many)
#include <vector>
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
std::vector<int> arr(n); // allocate n elements
//find all combinations
findCombinationsUtil( &*arr.begin(), 0, n, n);
}
if compiler at least partially complies to C++11 e.g. it's late gcc 4.6 or higher or VS2010 and higher, then there is method data() that returns pointer to internal storage. But better to rewrite, templatize or overload findCombinationsUtil to use a container or iterator
void sortAllWay(int arr[][N])
{
// Consider matrix elements (in row major
// order) and sort the sequence.
int *ptr = (int*) arr;
sort(ptr, ptr + N * N);
}
What exactly does this piece of code do?
We passed an array to it, and it has been sorted. I have sorted arrays like sort(arr, arr + n) where n is the size of the array. However this doesn't make much sense to me.
That's just a function that calls real std::sort function for your array.
In case of arrays std::sort function gets pointer to the first element of an array and pointer to the end of an array (right after the last element).
Since statically allocated 2-dimensional array stores in memory as single sequence you can iterate over it by incrementing pointer ptr till it reaches ptr+N*N in your case.
int *ptr = (int *)arr; - pointer to the first element
ptr+N*N - pointer to the end of an array (right after the last element)
sort(arr, arr + n) is algorithm in the STL which sorts the elements in the array
A simple demo for sort algorithm
int arr[] = {1, 5, 8, 9, 6, 7, 3, 4, 2, 0};
int n = sizeof(arr)/sizeof(arr[0]);
sort(arr, arr+n);
cout << "\nArray after sorting using default sort is : \n";
for (int i = 0; i < n; ++i)
cout << arr[i] << " ";
Output :
Array after sorting using default sort is :
0 1 2 3 4 5 6 7 8 9
So by default,
sort() sorts an array in ascending order.
Click this link and study it .
Sort algorithm STL
Apperantly this code works
void printD(int * ar,int r)
{
for(int i = 0; i < r; i++)
cout<<ar[i]<<endl;
}
int main()
{
int ar[3] = {1,2,3};
printD(ar,3);
return 0;
}
But this code does not work
void print2D(int ** ar,int r,int c)
{
for( int i = 0; i< r;i++)
for(int j = 0; j < c;j++)
cout<<ar[i][j]<<endl;
}
int main()
{
int ar2[1][2] = {{3,1}};
print2D(ar2,1,2);
return 0;
}
I do not understand why this does not work?
The problem lies within how the memory addresses are calculated. a[0] is the first element, and a[1] is the second element, so the address of a[1] is the position of a[0] plus the size of the element. No problem here, the address of any element can be calculated with the position of the first element multiplied with the offset times the element size.
How does this work with multi-dimensional arrays? What's the distance between a[0][5] and a[1][5]? Well, that depends on the row size (I'm using this terminology for the sake of this example, in reality, there aren't any "rows"), since in the end it's just one block of memory. If a row has 10 elements, then the distance is 10 times the size of an element. So this row size is important, the exact location of the elements in the array can't be calculated without it. Now with this here:
void print2D(int ** ar,int r,int c)
How could it know that row size? ar[1][0] is the first element of the second row, so if a row had size 10, then that would be the 10th element in the memory block. However, if the row size is 20, then it would be the 20th element, and that would be a different address. So how would it know?
The code doesn't work because it would require information to calculate the addresses, but it doesn't have that information.
This array int ar2[1][2] actually decays to int(*)[2].
There is no intermediate pointer to pointer that gets allocated, there is a contiguous 1D array that has can be accessed in 2D, hence the remaining [2] that gives the stride to go from one row to another.
A 2-dimensional array is implicitly converted to a pointer to a 1D array, not to a pointer to a pointer.
void print2D(int (*ar)[2],int r,int c)
{
// definition omitted for brevity
}
int main()
{
int ar2[1][2] = {{3,1}};
print2D(ar2,1,2);
return 0;
}
There is also no conversion from a pointer to an array (as in the above sample) into a pointer to pointer.
For more dimensions, this also works - except that all dimensions other than the first must be known at compile time.
my aim is to reverse an array 3,12,2,1 to 1,2,12,3. when i run this code i get garbage before my actually result. i can't seem to see where the problem is please assit
#include<iostream>
using namespace std;
int rev (int arr[], int a){
//int r;
for(int i =a-1; i>=0; i--){
cout<<arr[i]<<" ";
}
return 0;
}
int main(){
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
cout<<rev(arr, sizeof(arr))<<endl;
system("pause");
return 0;
}
Use sizeof(arr)/sizeof(arr[0]) instead of sizeof(arr).
sizeof(arr) gives the total size of the array. sizeof(arr[0]) is the size of one array element (all elements have the same size). So sizeof(arr)/sizeof(arr[0]) is the number of elements.
An optimized answer to the question would be using reverse () from STL if you are allowed to use it:
std::reverse
http://www.sgi.com/tech/stl/reverse.html
int main()
{
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
reverse(arr, arr + 5);
copy(arr, arr + 5, ostream_iterator<int>(cout, ", "));
}
sizeof return the size in bytes. In your example, if sizeof(int) = 4, it returns 20.
Because you're using an array, you have to keep the size of the array handy as well. sizeof computes the size of a value in memory, in this case the size of all the memory used to represent arr. You can do sizeof(arr)/sizeof(int) to get the number of elements in an array. This makes sense because it's taking the total size of the array and dividing it by the size of an element in the array. Beware however that this only works for arrays (int arr[4] = {6,41,12,5,2};). If it's a pointer to a heap-allocated array via something like int* i = new int[4]; you'll need to keep the size of the array hanging around.
Also, you're calling your reverse function from within a cout<< call, which will print the function's return value (in this case it's hard-coded to 0).
It also turns out there is a function in the C++ standard library (std::reverse) that can do this.
If I may speak subjectively and in an off-topic manner about your approach, it is very un-C-like. My personal favorite way to reverse an array goes like this:
void reverse(int *a, int n)
{
int *p = a, *q = a + n - 1;
while (p < q)
{
int swap = *p;
*p++ = *q;
*q-- = swap;
}
}
// Usage:
int a [] = { /* ... */ };
reverse(a, sizeof(a)/sizeof(*a));
Of course, since your question is tagged c++, there's always std::reverse().
Sizeof operator return the one extra (arrayLength + 1) here 6 will return when passs 6 it store in a when a-1 you get 5 but array index start from 0 length-1 that from 0 to 4 here i pointing to index 5 that is not last element last+1 that why you got garbage value