I was working with 2D arrays, and tried passing it from one function to another. I've seen all the answers in here regarding that, and none of them seem to answer this particular type of problem. Its a simple thing I'm trying to achieve, but the answer is weird.
Here's the main():
int main(void)
{
int i=0,j=0,n=0,n2=0;
double **a, **a1, b=0;
printf("Enter 'n2' :");
scanf("%d", &n2);
a= makearray(n2);
for(i=0; i < n2; i++){
for(j=0; j < n2; j++){
a[i][j] = j;
printf("%.f ",a[i][j]);
}
printf("\n");
}
printf("\n\n\n");
for(i=0; i < n2; i++){ // print a
for(j=0; j < n2; j++){
b = a[i][j];
printf("%.f ", b);
}
printf("\n");
}
printf("\n\n\n");
return 0;
}
The function makearray() just returns a pointer to a pointer for the 2D array of size passed as an argument.
makearray() is:
double** makearray(int n2)
{
int i=0;
double** a;
a = malloc(n2 * sizeof(int *));
if(a == NULL){
fprintf(stderr, "out of memory\n");
exit(0);
}
for(i = 0; i < n2; i++){
a[i] = malloc(n2 * sizeof(int));
if(a[i] == NULL){
fprintf(stderr, "out of memory\n");
exit(0);
}
}
return a;
}
You can input 'n2', where (n2 x n2) becomes the matrix size , and with n=9, the output is:
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 0 1 2
0 1 2 3 4 5 6 7 8
I've not modified the first array in any way, just printed it again, any ideas why those two are different?
In your makearray, the malloc is using sizeof(int), but you're creating an array for doubles. Ints typically use 4 bytes, but doubles use 8 bytes. So you aren't malloc-ing enough memory for a 2-d array of doubles.
Try:
double** makearray(int n2)
{
int i=0;
double** a;
a = malloc(n2 * sizeof(double *)); //<- was sizeof(int *)
if(a == NULL){
fprintf(stderr, "out of memory\n");
exit(0);
}
for(i = 0; i < n2; i++){
a[i] = malloc(n2 * sizeof(double)); //<- was sizeof(int)
if(a[i] == NULL){
fprintf(stderr, "out of memory\n");
exit(0);
}
}
return a;
}
Related
I'm trying to take a N*N 2-D array, have each process be responsible for a number of columns, carry out an action on the elements and gather them back together into a single 2-D array again.
I have managed to divide the columns among the processes, carry out the action and bring them back together using MPI subarrays and Gatherv. However, when I give the program a number of processes that doesn't equally divide into the number of columns, the returned data is misplaced.
With the master matrix being 12x12, I provide four processes and get the correct result back:
FINAL MATRIX
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
When the matrix is still 12x12 and I provide five processes, I get this output:
FINAL MATRIX
1 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
Can someone inform me as to what I've configured incorrectly for this to be the result? Ultimately, after resolving this, I wish to switch the Gatherv to Allgatherv so that each process has the entire 2-D array locally for further alterations.
Update (11/04/2021)
As suggested by Gilles I have attempted to use column vectors instead but could not find a way in which to recombine with Gatherv. I believe my issue with my current solution may be due to displacements as manually altering these causes changes in the output (populating some of the zero cells).
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void print_matrix (double ** X, int rows, int cols)
{
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j)
printf ("%.0f ", X[i][j]);
printf ("\n");
}
}
double **alloc_2d_array(int m, int n) {
double **x;
int i;
x = (double **)malloc(m*sizeof(double *));
x[0] = (double *)calloc(m*n,sizeof(double));
for ( i = 1; i < m; i++ )
x[i] = &x[0][i*n];
return x;
}
void main(int argc, char *argv[]) {
int n = 12;
int ndims = 2;
int rank, size;
int root_rank = 0;
MPI_Datatype sendsubarray, recvsubarray, resizedrecvsubarray;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Report active to console
printf("Rank: %d, reporting!\n", rank);
// Make master matrix
double ** master_matrix = alloc_2d_array(n, n);
// Set starting values in master matrix
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
master_matrix[i][j] = 0;
}
}
// Calculate sub matrices no. of columns and displacements
int interval, modulus, section_end, section_start, section_length;
int counts[size];
int displs[size];
interval = n/size;
modulus = n % size;
for (int i=0; i < size; i++) {
if (modulus != 0) {
counts[i] = interval+1;
modulus--;
} else {
counts[i] = interval;
}
displs[i] = (i == 0) ? 0 : displs[i-1]+counts[i-1];
}
// Calculate subarray info
int master_size[2] = {n, n};
int subsize[2] = {n, counts[rank]};
int startat[2] = {0, displs[rank]};
// Populate sub matrix in main matrix
for (int i = startat[0]; i < startat[0] + subsize[0]; i++)
for (int j = startat[1]; j < startat[1] + subsize[1]; j++)
master_matrix[i][j] = rank + 1;
// Print adjusted matrix
// printf("ADJUSTED MATRIX\n");
// print_matrix(master_matrix, n, n);
// Create the subarray type for use by each send node (incl. the root):
MPI_Type_create_subarray(ndims, master_size, subsize, startat, MPI_ORDER_C,
MPI_DOUBLE, &sendsubarray);
MPI_Type_commit(&sendsubarray);
// Create the subarray type for use by the receive node (the root):
if (rank == 0) {
MPI_Type_create_subarray(ndims, master_size, subsize, startat, MPI_ORDER_C,
MPI_DOUBLE, &recvsubarray);
MPI_Type_commit(&recvsubarray);
MPI_Type_create_resized(recvsubarray, 0, 1 * sizeof(double),
&resizedrecvsubarray);
MPI_Type_commit(&resizedrecvsubarray);
}
// Gather the send matrices into the receive matrix:
MPI_Gatherv(master_matrix[0], 1, sendsubarray,
master_matrix[0], counts, displs, resizedrecvsubarray,
0, MPI_COMM_WORLD);
if (rank == 0) {
printf("FINAL MATRIX\n");
print_matrix(master_matrix, n, n);
}
MPI_Finalize();
}
Print all n! permutations of the number 1,2,3,...,n.
Example: Input: 3
Output: 1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Following is my approach. My program is not working for inputs greater than 3. I understand the logic why it is not working , but I am unable to translate that logic into a code block to overcome that issue.
#include <stdio.h>
int permute(int n)
{
int a[n];
int i,j,k,store;
for(i=0;i<n;i++)
a[i]=i+1;
for(i=1;i<=n;i++)
{
for(j=0;j<n-1;j++)
{
store=a[j+1];
a[j+1]=a[j];
a[j]=store;
for(k=0;k<n;k++)
printf("%d ",a[k]);
printf("\n");
}
}
}
int main()
{
int n;
scanf("%d",&n);
permute(n);
return 0;
}
Following is the output for n as 4:
We can clearly see that some permutation are missing, and I know exactly the fault in my code. But I am unable to fix it.( I am a beginner , hence I don't know much advanced C libraries or functions)
One solution consists in calling the function recursively: you set the first number (n possible choices), then call the function for a size n-1.
Output, for n=4
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 3 1
2 4 1 3
3 2 1 4
3 2 4 1
3 1 2 4
3 1 4 2
3 4 1 2
3 4 2 1
4 2 3 1
4 2 1 3
4 3 2 1
4 3 1 2
4 1 3 2
4 1 2 3
#include <stdio.h>
#include <stdlib.h>
void swap (int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
}
void permute(int index, int* arr, int n) {
if (index == n-1) {
for (int k = 0; k < n; ++k) {
printf ("%d ", arr[k]);
}
printf ("\n");
return;
}
for (int i = index; i < n; i++) {
swap (arr + index, arr + i);
permute (index+1, arr, n);
swap (arr + i, arr + index);
}
return;
}
int main()
{
int n;
if (scanf("%d",&n) != 1) exit (1);
int arr[n];
for (int i = 0; i < n; ++i) arr[i] = i+1;
permute(0, arr, n);
return 0;
}
I am trying to get my program to count down after counting up to ten. I have tried to alter the code from counting up to make it count down to no avail.
#include <stdio.h>
void count(int k)
{
if (k > 0) {
count(-k + 1);
printf("%d", k);
}
else {
if (k == 0)
{
printf("%d,", k);
}
else {
count(k + 1);
printf("%d,", -k);
}
}
}
int main(int argc, char ** argv)
{
count(10);
getchar();
return 0;
}
Here is a simple example of the recursion which does this, illustrating Eugene's comment:
#include <stdio.h>
void count(int n) {
if (n > 10) {
printf("\n");
return;
}
printf("%d ", n);
count(n+1);
printf("%d ", n);
}
int main() {
count(0);
printf("\n");
return 0;
}
it counts up on the way into recursion and counts down while it exits it. Actually on the way down it only re-prints the state which it was before diving into the next level:
0 1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1 0
The function can be easy implemented if to use a static local variable inside it. For example.
#include <stdio.h>
void count(unsigned int n)
{
static unsigned int m;
printf("%u ", m);
if (n != m)
{
++m;
count(n);
--m;
printf("%u ", m);
}
}
int main( void )
{
const unsigned int N = 10;
unsigned int i = 0;
do
{
count(i);
putchar('\n');
} while (i++ != N);
return 0;
}
The program output is
0
0 1 0
0 1 2 1 0
0 1 2 3 2 1 0
0 1 2 3 4 3 2 1 0
0 1 2 3 4 5 4 3 2 1 0
0 1 2 3 4 5 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 0
Within the function the static variable m behaves as an index in a for loop (or there will be more suitable a do-while loop).
At first it is initialized implicitly by zero (as any static variable)
static unsigned int m;
You can use the initializer explicitly if you want
static unsigned int m = 0;
then it is changed from 0 to n and afterward backward from n again to 0.
++m; // changing from 0 to n
count(n);
--m; // changing from n to 0
I'm trying to do an inverted triangle with numbers using C. I think the number part of the code is right, but the spacing isn't working.
#include <stdio.h>
//Declare function
int triangle(int n);
//Main
int main(void){
int height;
do{
printf("height:");
scanf("%d", &height);
}while (height < 1 && height > 9);
triangle(height);}
//Function
int triangle(int n)
{
int x,j,linhas, spaces;
//Number of lines
for(linhas = 0; linhas < n; linhas++){
//Print spaces NOT FUC****** WORKING!!!
for(spaces =0; spaces < (linhas + 1); spaces ++){
printf(" ");}
//Fill in the numbers
do{
//Increasing part till n
for (x = 0; x < n; x++){
printf(" %d ", (x+1));}
//Decreasin part from n
for (j = 0; j < (n-1) ; j++){
printf(" %d ", ((n-1) -j));}
//New line after each line
printf("\n");
n--;
}while(n > 0);}}
the output is :
height:5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Anybody can help on the spacing the output should be:
height:5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
So, the problem are in do loop. You decrease the count (variable n), stay in loop until n>0 and the 'spaces for' do one time. Try doing like this.
int triangle(int n)
{
int x,j,linhas, spaces, m;
//Number of lines
m=n;
for(linhas = 0; linhas < n; linhas++){
for(spaces =0; spaces < linhas; spaces ++){
printf(" ");
}
//do{
for (x = 0; x < m; x++){
printf(" %d ", (x+1));
}
for (j = 0; j < (m-1) ; j++){
printf(" %d ", ((m-1) -j));
}
printf("\n");
m--;
//}while(n > 0);
}
}
Your code is messed up. It should have 2 nested loops, like this:
while (n > 0)
{
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
Then you stuff your spaces inside the 1st nesting layer:
while (n > 0)
{
for (...) // print spaces
{
}
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
However, you have 3 nested layers!
for (linhas ...) // useless code - you should remove it!
{
for (...) // this code is misplaced
{
}
while (n > 0)
{
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
}
The outer loop does just on iteration (because on the second iteration n is 0, and it exits). This code is unneeded and confusing - remove it, and then you will see where to place your code that prints spaces.
My five cents.:)
You can output the first digit separatly using symbol * as the field width in the format specifier and an appropriate number.
For example
printf( "%*u", 2 * i + 1, j );
^^^
Here is a demonstrative program
#include <stdio.h>
int main( void )
{
while ( 1 )
{
printf( "Enter the height of the pyramid (0- exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
printf( "\n" );
for ( unsigned int i = 0; i < n; i++ )
{
unsigned int j = 1;
printf( "%*u", 2 * i + 1, j );
while ( !( n - i < j + 1 ) ) printf( " %u", ++j );
while ( --j != 0 ) printf( " %u", j );
printf( "\n" );
}
}
return 0;
}
If to enter sequentially
9 8 7 6 5 4 3 2 1 0
then the program output is
Enter the height of the pyramid (0- exit): 9
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 8
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 7
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 6
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 4
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 3
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 2
1 2 1
1
Enter the height of the pyramid (0- exit): 1
1
Enter the height of the pyramid (0- exit): 0
you should try (keeping most of your code)
//Function
int triangle (int n)
{
int x, j, linhas, spaces;
int orig_n = n;
//Number of lines
for (linhas = 0; linhas < n; linhas++)
{
do
{
for (spaces = 0; spaces < (orig_n - n) * 3; spaces++)
{
printf (" ");
}
//Fill in the numbers
//Increasing part till n
for (x = 0; x < n; x++)
{
printf (" %d ", (x + 1));
}
//Decreasin part from n
for (j = 0; j < (n - 1); j++)
{
printf (" %d ", ((n - 1) - j));
}
//New line after each line
printf ("\n");
n--;
}
while (n > 0);
}
}
How can I use array pointer (int *) to create and print this kind of 2d array:
0 1 2 3 4 5 6 7 8...
1 2 3 4 5 6 7 8 9...
2 3 4 5 6 7 8 9 10...
3 4 5 6 7 8 9 ...
4 5 6 7 8 9...
5...
I currently have this code:
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int * matrix, int row, int column)
{
puts("Begin creating matrix.");
int i, j;
for(i = 0; i < row; i++)
{
for(j = 0; j < column; j++)
{
*(matrix) = i + j;
matrix++;
}
}
puts("Success!");
}
int printMatrix(int * matrix, int row, int column)
{
puts("Begin printing matrix!");
int i, j, valuesPrinted;
for(i = 0; i < row; i++)
{
for(j = 0; j < column; j++)
{
printf("%5d ", *(matrix + i * j));
valuesPrinted++;
}
puts("");
}
puts("Printing success!");
return valuesPrinted;
}
int main()
{
int row = 11;
int column = 13;
int * matrix = malloc(sizeof(int) * row * column);
createMatrix(matrix, row, column);
printMatrix(matrix, row, column);
return 0;
}
What I want to do is: use declare array and assign to pointer, then pass the pointer to a function and give it values as above. I think the problem is in the way I initialize the 2D array by pointer and access it.
And the result is:
0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 6 8 10 12 2 4 6 8 10 12
0 3 6 9 12 3 6 9 12 3 6 9 12
0 4 8 12 4 8 12 4 8 12 4 8 12
0 5 10 3 8 13 6 11 4 9 14 7 12
0 6 12 6 12 6 12 6 12 6 12 6 12
0 7 2 9 4 11 6 13 8 15 10 17 12
0 8 4 12 8 4 12 8 16 12 8 16 12
0 9 6 3 12 9 6 15 12 9 18 15 12
0 10 8 6 4 14 12 10 8 18 16 14 12
int *matrix = malloc(sizeof(int) * row * column);
// could better be written as
int *matrix = malloc((row*column) * sizeof *matrix);
The above statement dynamically allocates an array of integers of size row * column. If you want to access the elements of this array as you would access elements of a 2D array, then the element at row i and column j has the index
i * column + j
Modify your printMatrix function to -
int printMatrix(int * matrix, int row, int column)
{
puts("Begin printing matrix!\n");
int i, j, valuesPrinted;
for(i = 0; i < row; i++)
{
for(j = 0; j < column; j++)
{
// this is equivalent and more readabable
// printf("%5d ", matrix[i*column + j]);
printf("%5d ", *(matrix + i*column + j));
// ^ note i is multiplied by column
valuesPrinted++;
}
puts("");
}
puts("Printing success!\n");
return valuesPrinted;
}
Your printing code is using the wrong expression to access the elements of the matrix. You've got:
printf("%5d ", *(matrix + i * j));
You need:
printf("%5d ", *(matrix + i * column + j));
Or:
printf("%5d ", matrix[i * column + j]);
printf("%5d ", *(matrix + i * column + j));
instead of
printf("%5d ", *(matrix + i * j));