Addition of sparse matrix using structure in c(triplet form) - c

I am currently doing a problem of addition of sparse matrices. I am making sparse matrix by using triplet form. The triplet form is made by using structure in c.
struct sparse
{
int row;
int col;
int val;
};
but while doing this sparse matrix problem I encountered a problem that my code only displays the correct sparse matrix when i am giving the indices of nonzero values in increasing order (eg. (0 1 3),(1 2 5),(2 2 7) etc)otherwise it is displaying incorrect matrix.for example if am giving input like (0 1 3),(2 2 7),(1 2 5) etc then it is displaying wrong matrix. How to solve this problem so that in any order of indices it will give correct output?
I have added my input and resulting output. I have done this for two sparse matrix.
#include<iostream>
#include<cstdio>
struct sparse
{
int row,col,val;
};
void readmat(sparse sp[])
{
printf("enter total number number of rows ,column of matrix and total
of nonzero values in this\n");
scanf("%d %d %d",&sp[0].row,&sp[0].col,&sp[0].val);
printf("now start entering the values by specifying index
position\n");
for(int i=1;i<=sp[0].val;i++)
scanf("%d %d %d",&sp[i].row,&sp[i].col,&sp[i].val);
}
void displaymat(sparse sp[])
{
int k=1;
for(int i=0;i<sp[0].row;i++)
{
for(int j=0;j<sp[0].col;j++)
{
if(k<=sp[0].val&&i==sp[k].row&&j==sp[k].col)
{
printf("%d\t",sp[k].val);
k++;
}
else
printf("0\t");
}
printf("\n");
}
}
int main()
{
struct sparse sp1[10],sp2[10],sp3[10];
printf("for first matrix\n");
readmat(sp1);
printf("for second matrix\n");
readmat(sp2);
displaymat(sp1);
printf("\n\n");
displaymat(sp2);
printf("\n\n");
displaymat(sp3);
return 0;
}`

Updating the original answer:
The reason out of order values are not getting printed is because when the value in triplet form points to an element further down the for loops go past all the other values that could have been printed. For example in your example the 3rd element is at row=1, col=3 however the 2nd element is at row=2,col=2. This will lead to the outer for-loop advancing down to 2nd row. At that point in time the loops will not go back and print 1st row.
One way will be to sort based on the row and col and then print the values.

Related

Print a matrix line from a sparse matrix saved without 'zeros'

How do I print a matrix line between 2 column indexs when I only have the non-zero indexes saved in a struct?
I need to basically, given the right most index of a matrix and the left most index of a matrix, print that matrix line between both values if there's at least one index in that line that isn't zero and if the line I want to print is between the row's bound.
I have a structure in which I store my row, column and value from each input, so that I don't have to generate a huge matrix full of 'zeros' and I have a variable that counts how many values I have stored.
int searchForLine(unsigned int l){
int i;
for(i=0;i<matrixcount;i++){
if((auxMatrix[i].line == l)&&(auxMatrix[i].column<=workingMatrix.maxCol)&&(auxMatrix[i].column>= workingMatrix.minCol))
return (int)auxMatrix[i].value;
}
return (int)workingMatrix.zero;
}
void print_line(){
unsigned int ii,i,userLine;
scanf("%u", &userLine);
if((userLine<workingMatrix.minLine) || (userLine>workingMatrix.maxLine)){
printf("empty line\n");
}
else{
for(ii=0;ii<matrixcount;ii++){
if(auxMatrix[ii].line!=userLine){
printf("empty line\n");break;
}else{;}
}
for(i=workingMatrix.minCol;i<workingMatrix.maxCol;i++){
printf("%u ",searchForLine(userLine));
}
}
printf("\n");
}
if the input is lets say
3 3 3.0
3 0 4.0
print_line(3)->
4.0 0.0 0.0 3.0
My current code prints only 0.0's

Nested for loop saving last input not whole input

I'm back again with that C question heh. So I'm trying to get the user to input a whole 2d array (size, values, everything), with VLA arrays (im using the latest compiler). Everything is fine up until I get the nested for loop, then it saves the last value into the array and ignored anything before it. I cannot seem to figure out how to fix my VLA to iterate through every element in the array and assign the value typed in by the user, all I get is it saving my last value into the whole array. Through some testing I've found that my problem is contained in my Inner loop of my nested for loop. EDIT: Through the help of Weather Vane, it was figured out that the array needs to be initialized after my x and y are saved, but now it saves my last value in the whole array and not every value typed. Here's my code snippet:
int x, y, row, col, a = 0;
//int NxM[x][y]; Moved
bool counter[10]; //I have 1 last part to code that involves this
printf("This program counts occurrences of digits 0 through 9 in an NxM
array.\n");
printf("Enter the size of the array (Row Column): ");
scanf("%d %d", &x, &y);
int NxM[x][y]; //Moved here.
for(row = 0; row < x; row++){
printf("Enter row %d: \n", a);
a++;
for(col = 0; col < y; col++){
scanf("%d ", &NxM[x][y]);//Why you only save 1 value >.<
}
}
(The reason I have my printf statement between my loops was to test where my looping problem was, and because I need my printf to look like Enter row 0 Enter row 1 etc..)

C programming error.2Darrays

I have the code below.The problem is that I am taking a two dimensional array with a rows and 2 col.The 1st col is for storing values and 2nd as a flag.The problem arises when I initialize my flag the values are also getting affected.
#include<stdio.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
int arr[a][1];
int i,j,k,sum=0;
for(i=0;i<a;i++)
{
scanf("%d",&arr[i][0]);
}
for(i=0;i<a;i++)
{
printf("%d\n",arr[i][0]);
}
for(j=0;j<a;j++)
{
arr[j][1]=0;
}
for(i=0;i<a;i++)
{
printf("%d\n",arr[i][0]);//Different Values
}
}
int arr[a][1]; There is only one column and not two.You should use
int arr[a][2];
Here you write out of bounds
arr[j][1]=0;
This is because you write to the second element of an array with only one element.
The size of arr[x] (for any valid x) is just one.
Writing out of bounds leads to undefined behavior.
Your arrays should be something like this :
arr[row][col] where row denotes the number of rows and col the no of coloumns.
Therefore arr[a][1] is a array of a rows and 1 coloumn and therefore your code works wrong.
Your array should be a[a][2]. It means arr is a array with a rows and 2 coloumn.Similarly you have to change the other arr[][] 's throughout the code.

C : recursively defined program to calculate determinant of a matrix

I cannot understand why this program is producing wrong determinant values for matrices. This program uses the recursive calls to the function func() which converts the argument matrix to its minor which is then ultimately reduced to a single element. Please help, What is the error in this code..??
#include<stdio.h>
#include<math.h>
void display_(int arr[][4])
{
int i,j;
putchar('\n');
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
printf("%d\t",arr[i][j]);
printf("\n");
}
}
int func(int arr[][4],int i,int j,int order)
{
if(order==1)
return arr[0][0];
return(pow(-1,i+j)*arr[i][j]*func(arr,i+1,j+1,order-1));
}
int main()
{
int i,j,matrix[4][4];
printf("\nEnter the elements to the matrix : ");
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%d",&matrix[i][j]);
display_(matrix);
printf("\nDeterminant : %d",func(matrix,0,0,4));
}
That is not the correct formula. See here.
Do you want to implement the Laplace formula? In that case, you need a sum over all rows and then recursively calculate the minors. That are the determinants of the matrix that results from A by removing the i-th row and the j-th column. That is where you use your function recursively.
Or do you want to implement the Leibniz formula? In that case, you need a sum and iterate over all possible permutations and then a product where you iterate over the number of rows (or columns). But you don't need recursion there.
Note that there are quite a few similar questions here on SO, e.g. here or here.

Segmentation fault in C with only certain inputs

Okay, so I'm trying to solve the Knapsack problem.
On small input cases the program runs with no problem and provides the optimal solution, however when the input size is large, or rather the numbers in the input file become large, the program gives me a segmentation fault. I don't quite get why is this happening since the max value of INT exceeds any of these numbers too.
Here's my code.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int W,n,i,j,k ;
scanf("%d %d",&W,&n); // capacity of knapsack and number of total items
int value[n+1],weight[n+1];
int** A;
A = (int **)malloc((n+1)*sizeof(int*));
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
for(i=1;i<n+1;i++)
{
scanf("%d %d",&value[i],&weight[i]); //taking value and weight of each item
}
for(i=0;i<W+1;i++)
A[0][i]=0;
for(i=0;i<n+1;i++)
A[i][0]=0;
for(i=1;i<n+1;i++)
{
for(j=1;j<W+1;j++)
{
if(j-weight[i]<0)
{
A[1][j]=A[0][j];
}
else
{
if(A[0][j]>A[0][j-weight[i]]+value[i])
A[1][j]=A[0][j];
else
A[1][j]=A[0][j-weight[i]]+value[i];
}
}
for(k=0;k<W+1;k++)
A[0][k]=A[1][k];
}
int max=0;
i=1;
for(i=0;i<2;i++)
for(j=0;j<W+1;j++)
{
if(A[i][j]>max)
max=A[i][j];
}
printf("%d\n",max);
return(0);
}
It runs perfectly for this input http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack1.txt
But when the input size is the one given in the link, it provides a seg fault http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack2.txt
Thanks for the help!
When allocating the arrays for the 2nd dimension you do:
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
It should be n+1 instead of W+1 in the loop. You should iterate over the "items" dimensions and allocate "weight" dimension.
The solution will work perfectly for n <= W, but for larger number of items (W < n) - you will get undefined behavior, because you are trying to access A[n][0] at some point, but you did not allocate the array for the nth item.
So basically - you need to change the initialization of the 2nd dimension to:
for(i=0;i<n+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));

Resources