I've this piece of code which is working by now(at least):
int** constructSparseMatrix(int totalRow, int totalCol, int totalEl) {
int** arr = new int*[totalEl];
//int x = 0;
for(int i = 0; i < totalEl; i++) {
arr[i] = new int[totalCol];
for (int k = 0; k < totalCol; k++) {
if(k == totalCol - 1) {
arr[i][totalCol - 1] = rand () % 101;
} else {
arr[i][k] = rand () % totalRow + 1;
}
}
}
return arr;
}
and I'm trying to access the element inside by using pointer instead of array and here is my try:
int** constructSparseMatrix(int *totalRow, int *totalCol, int totalEl) {
int** arr = new int*[totalEl];
//int x = 0;
for(int i = 0; i < totalEl; i++) {
arr[i] = &totalCol [0];
for (int k = 0; k < *totalCol; k++) {
if(k == *totalCol - 1) {
arr[i][*totalCol - 1] = rand () % 101;
} else {
arr[i][k] = rand () % *totalRow + 1;
}
}
}
return arr;
}
But when I initialize the same way as the working function:
int** arr = constructSparseMatrix(5,3,totalEl);
then I receive this error:
argument of type "int" is incompatible with parameter of type "int *"
First of all, is my conversion from array to pointer version coded properly? If it's correct, how can I initialize it to avoid above error?
First of all it is obvious that this statement in the function
arr[i] = &totalCol [0];
is wrong. It does not make sense.
You declared the function
int** constructSparseMatrix(int *totalRow, int *totalCol, int totalEl);
as having the first and second parameters as pointers but are trying to pass integer literals 5 and 3 to it in the call
int** arr = constructSparseMatrix(5,3,totalEl);
You could write for example
int totalRow = 5;
int totalCol = 3;
//...
int** arr = constructSparseMatrix( &totalRow, &totalCol, totalEl );
But I do not see a sense to declare these parameters like pointers because they are in fact constants within the function that is they are not changed.
And the variable names confuse the reader. For example I would expect that totalRow is used within the function in statement
int** arr = new int*[totalRow];
instead of totalEl
If you want to use pointers within the function then the function can look like
int** constructSparseMatrix( int totalRow, int totalCol, int totalEl )
{
int** arr = new int*[totalEl];
for ( int **p = arr; p < arr + totalEl; ++p )
{
*p = new int[totalCol];
for ( int *q = *p; q < *p + totalCol; ++q )
{
if ( q == *p + totalCol - 1 )
{
*q = rand () % 101;
}
else
{
*q = rand () % totalRow + 1;
}
}
}
return arr;
}
I think you are passing constants 5 and 3 as arguments which causes this error.
you can't pass constant value as it is by reference.Try passing 5 and 3 by storing them in a variable.
Related
void * bubbleSort(void * data){
int * str;
str = (int* ) data;
int temp = 0;
for ( int i = 0 ; i < len ; i++ ){
for (int j = i + 1; j < len ; j++ ){
if(str[i] > str[j]){
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
}
}
int main(){
int *data= new int[1000000];
...
pthread_t thread[input];
for ( int i = 0 ; i < input ; i ++){
pthread_create(&thread[i],NULL,bubbleSort,arguments);
pthread_join(thread[i],NULL);
}
}
I have int *data[1000000] and I want to use pthread to pass parameter to bubble sort.
The above is the code I wrote, but it is no output
How to successfully work ?
To fix your immediate problem: your data variable is defined with the wrong type.
int *data[1000] is an array of 1000 int *, which decays to int**. Your bubbleSort function expects an int *.
Declare data as follows instead:
int * data = new int[10000];
and then you can simply pass it to pthread_create as a void* like you do now.
However, modern C++ has a std::thread which is far easier to work with:
std::thread sorter(bubbleSort, data);
sorter.join();
need a better approach to pass address arr[0][2], given that is has to be received in a double pointer.
want to pass arr[0][2] without storing in any other variable.
#include <iostream>
using namespace std;
int help(int **arr)
{
cout<<**arr;
}
int main()
{
{
int n=3,m=3,k=0;
int **arr = new int*[n];
for(int i = 0; i < n; i++) {
arr[i] = new int[m];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
arr[i][j]=k;
k++;
}
}
int *g=*arr+2;
int **h=&g;
help(h);
}
}
There is no better way. Unfortunately C++ syntax x[y] can be used to mean two very different operations: if x is an array then is indexing, if x is a pointer they it's indirection and indexing.
If a caller expects a pointer to a pointer and you've a bidimensional matrix there's nothing you can do except actually creating the pointer that is not present in the matrix and pass its address.
The fact that with an array of pointers, with a pointer to a pointer and with a 2d array the syntax to reach an element is x[y][z] is irrelevant... they are three very different operations.
Why not just write
int *p = &arr[0][2];
help( &p );
If you want to get an access to the whole array using a pointer of the type int ** then you can use the following approach.
#include <iostream>
void help(int **arr, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
std::cout << ( *arr )[i] << ' ';
}
std::cout << '\n';
}
int main()
{
int arr[2][3]={{1,2,3},{4,5,6}};
int *p = reinterpret_cast<int *>( arr );
help( &p, 6 );
return 0;
}
The program output is
1 2 3 4 5 6
struct Test1 {
struct Test2 {
DWORD VA1 = 0;
DWORD VA2 = 0;
Test2(DWORD hp):VA1(hp) { }
} *Ppy[5];
Test1() {
for (int i = 0; i < 5; i++)
*(Ppy + i) = new Test2((DWORD)i+2);
}
~Test1() {
for (int i = 0; i < 5; i++)
delete *(Ppy + i);
}
};
void main() {
Test1*Als = new Test1;
for (int i = 0; i < 5; i++)
Als->Ppy[i]->VA2;
// doesn't work-> cout << Als->*(Ppy + i)->VA2 << endl;
delete Als;
}
Hello
How to convert this whole line(if possible) or at least Ppy[i] to
Pointer style/arithmetic : Als->Ppy[i]->VA2
Something like this but it doesn't work : Als->*(Ppy + i)->VA2
Is there a way to make this even more complex (not asm deep)?
Instead of:
Als->Ppy[i]->VA2;
You can write:
(*(Als->Ppy + i))->VA2;
The pointer to the array is Als->Ppy
The pointer to an element of the array is Als->Ppy + i
The value of an element of the array is *(Als->Ppy + i)
The value of an element of the array is itself a pointer, and you need to wrap the above expression in parens before using it to point to an element of the structure.
I'm having a hard time with this little project of mine; can someone help me out? I am trying to take a pointer to an array, a number, and remove the number if it is present in the array. If the number is removed, the array shrinks. Please note at the time of running removeNumber size = 6.
main
{
int size = 5; // setting array size
int *a = new int[size]; // allocating dynamic array
// initializing array
a[0] = 0; a[1] = 10; a[2] = 20; a[3] = 30; a[4] = 40;
removeNumber(a, 10, size);
}
And now the prototype:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
if (index != -1)
{
for (int i = number; i <= size; ++i)
newArray[i] = *&arrayPtr[i + 1];
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}
Check for reference:
int check(int *arrayPtr, int number, int size)
{
for (int i = 0; i < size; i++)
{
if (arrayPtr[i] == number) return i;
}
return -1;
}
The function is wrong. First of all it has a memory leak in case when the target value is not found in the array.
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (index != -1)
{
//...
}
}
Secondly there is used incorrect range of indices
for (int i = number; i <= size; ++i)
^^^^^^ ^^^^^^^^^
newArray[i] = *&arrayPtr[i + 1];
^^^^^^
And you could write this expression *&arrayPtr[i + 1] simpler just like arrayPtr[i + 1].
You forgot to copy the elements of the original array before the index index. number is not a valid index.
Also it would be better if the function returned a Boolean value saying whether the operation was successful or not. You can change the size of the array in the calling function if the call was successful.
So I would write the function like
bool removeNumber( int * &arrayPtr, int n, int value )
{
int index = check( arrayPtr, number, size );
if ( index != -1 )
{
int *tmp = new int[size - 1];
int i = 0;
for ( ; i < index; ++i ) tmp[i] = arrayPtr[i];
for ( ; i < size - 1; i++ ) tmp[i] = arrayPtr[i+1];
delete [] arrayPtr;
arrayPtr = tmp;
}
return index != -1;
}
It is ok to reinvent the wheel in order to learn. However you should be aware of the standard way to handle this: using std::vector along with std::remove/std::remove_if (defined in #include <algorithm>) would make your life much simpler, with the benefit of a performant implementation.
void removeNumber(std::vector<int>& vec, int number) {
vec.erase(std::remove(std::begin(vec), std::end(vec), number),
std::end(vec));
// If you really want to shrink the vector, you can call...
vec.shrink_to_fit();
}
I also made a little demo to show you that it works as intended.
Your problem is here:
for (int i = number; i <= size; ++i)
First of all you start the iteration from the value of the number that you searched(in your case 10) and as a result you will not enter the for loop.So the correct starting value of i is the first number of the array which is 0.Then this line of code here:
newArray[i] = *&arrayPtr[i + 1];
doesn't even make sense(as a thought process not syntactically), but what i think you want to do here is just copy the correct element from the old array to the new one.
A correct implementation of the previous is the following code:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
if (index != -1)
{
int *newArray = new int[size - 1];
int i = 0,j=0; //i for the old array and j for the new
while(i < size)//while we are in bounds
{
if(i==index)//if the index is the index of the given element
{ //skip this number
i++;
continue;
}
newArray[j++] = arrayPtr[i++];//copy the correct number to the correct position
}
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}
Input :
A[4] = {0,4,-1,1000} - Actual Array
P[4] = {1,0,3,2} - Order to be reshuffled
Output:
A[4] = {4,0,1000,-1}
Condition : Don't use an additional array as memory. Can use an extra variable or two.
Problem : I have the below program in C++, but this fails for certain inputs of array P.
#include<iostream>
using namespace std;
void swap(int *a_r,int *r)
{
int temp = *r;
*r = *a_r;
*a_r = temp;
}
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0] , dest = P[0];
for(int i=0; i<4;i++)
{
swap(&A[dest],&value);
dest = P[dest];
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
}
Since you've got a spare array called P kicking around, and there isn't anything in the question as quoted that stipulates it must be treated as a constant array, you could do:
for (i = 0; i < 4; i++)
P[i] = A[P[i]];
for (i = 0; i < 4; i++)
A[i] = P[i];
If you're not allowed to modify P, then you have to work a lot harder (and you also have to work a lot harder if the data type of A is not the same as, or compatible with, the type of P).
However, I fear this is a sleight-of-hand trick that doesn't really answer the question; it gets the job done, but doesn't answer the question.
First of all, I really like Jonathan's solution, but I feel like I can add some interesting ideas too.
The main observation is that array P consists of several loops.
Let's consider p = {1, 4, 3, 2, 0, 5}. There're three loops: 0 => 1 => 4 => 0, 2 => 3 => 2 and 5 => 5. And to replace variables alongside one loop we need no additional memory at all. We just go through it like this
do {
a[i] = a[p[i]];
i = p[i];
} while (i != first_i);
(The last element needs to be taken special care of, though.) The full working version:
for (int i = 0; i < n; ++i) {
if (p[i] < 0) {
// been at index 'i' already
continue;
}
// new loop found
int j = i;
int first_value = a[i]; // to be put in last position in the chain
int prev_j; // we always store previous 'j' index
do {
a[j] = a[p[j]];
prev_j = j;
j = p[j]; // move to next 'j'
p[prev_j] = -1; // mark element as processed
} while (i != j);
a[prev_j] = first_value;
}
The only problem with my solution is that it uses p array to mark element as 'processed'. Some interviewers may consider it ok, others - not, depending on the solution they have in mind.
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
Slightly modified to calculate dest value
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0], dest = P[0];
for(int i=0; i<4-1;i++)
{
int count=0;
dest = P[i];
while(dest<i){ //if P[i] points to lower value, it got swapped with some other position.
dest = P[dest];
}
swap(&A[dest],&A[i]);
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
cout<<"\n";
}
Could argue that it goes against the spirit of the question - but can use multiple stack instances (from a run-time perspective) of a single local variable (code perspective). Being allowed to mutate P is just as uncertain, so, FWIW - a recursive answer...
template <int N>
void shuffle(int (&a)[N], int p[], int i = -1)
{
if (++i < N)
{
int result = a[p[i]];
shuffle(a, p, i);
a[i] = result;
}
}