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

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

Related

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

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.

How to store this kind of data in an array

The input consists of multiple lines.
The first line contains a number n which indicates that the number of rows in the Pascal’s triangle will be n+1.
The second line contains a number m which indicates the number of transactions to be performed on the Pascal’s triangle. Each transaction is given in a separate line. A transaction is a space separated list of integers. The first integer in each list indicates the row number, say R, and the rest of the integers in the list indicate the indices of values in row R. For each transaction, you have to compute the sum of given coefficients in the given row R.
Example: Input will be given in the following format:
5
3
3 1 2
5 1 1 1 4
4 2 3 2
what should be done to store the values of transition lines like
3 1 2
5 1 1 1 4
4 2 3 2
under a single array variable.So that it can be passed to a function completely.
If you make a structure like this you might be able to do what you are trying to do. You can pass structure to function to compute sum of each line.
struct pascaltirangle
{
int size; //The no of lines
int* no_transactions; //To store no of transactions of each line
int** contents; //To store contents of each line. No of contents in line determined by transaction[i]
} dat;
//code to take input of size
dat.no_transactions=(int*)malloc(sizeof(int) * (dat.size+1));
//code to take no of transaction for each line
for(int i=0;i<=dat.size;i++)
contents[i]=malloc(sizeof(int)*dat.no_transaction[i]);
//code to take input for contents[i][j]
It simply adds all the transactions for a line using recursive function.
#include <stdlib.h>
#include <stdio.h>
int add_transaction(int *contents,int size)
{
if(!size)
return 0;
return (*contents + add_transaction(contents+1,size-1));
}
void main()
{
int size; //The no of lines
int* no_transaction; //To store no of transactions of each line
int** contents; //To store contents of each line. No of contents in line determined by transaction[i]
int c1,c2;
printf("Give size of triangle :");
scanf("%d",&size);
no_transaction=(int*)malloc(sizeof(int) * (size+1));
contents=(int**)malloc(sizeof(int)*(size+1));
for(c1=0;c1<=size;c1++)
{
printf("\nGive no of transaction for line no %d :",c1+1);
scanf("%d",no_transaction+c1);
contents[c1]=(int*)malloc(sizeof(int)*no_transaction[c1]);
for(c2=0;c2<no_transaction[c1];c2++)
{
printf("\tFor line %d give transaction no %d :",c1+1,c2+1);
scanf("%d",contents[c1]+c2);
}
}
printf("\nThe sum of the series is :");
for(c1=0;c1<=size;c1++)
{
if(c1)
printf("+ %d ",add_transaction(contents[c1],no_transaction[c1]));
else
printf(" %d",add_transaction(contents[c1],no_transaction[c1]));
}
//Code to free the allocated memory.
}

Ascending order arrangement of numbers of a file

How to read a file which contains two columns and sort the first column numbers in ascending order and to print them with their corresponnding 2nd column values using C ?
fopen opens a file.
fscanf reads from a file and splits what is read into bits according to a format specification (e.g. "%d %s" means an integer followed by whitespace followed by a string of non-whitespace characters).
qsort is a standard library function that will sort an array. It sorts the array by comparing one item to another item. You give it the name of a function (which you write) that does this comparison.
I encourage you to read the manual pages for these functions if you are not familiar with them.
The program below uses all this to:
Open a file test.txt
Read lines from the file into an array arr
Sort the array using qsort, using the rowcmp function (rowcmp looks at the numerical value in the first column to determine whether one element is greater than, equal to, or less than another element)
Print out the elements of the array.
The code...
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100
#define MAXITEMS 100
// A row has two columns, the first is a number and
// the second is any string of up to MAXLEN chars
struct row {
int col1;
char col2[MAXLEN];
};
// Function to do comparison of rows
// Sorts numerically on the value in the first column
int rowcmp(struct row * r1, struct row * r2) {
if (r1->col1 < r2->col1) return -1;
if (r1->col1 == r2->col1) return 0;
return 1;
}
int main(int argc, char ** argv) {
struct row arr[MAXITEMS]; // up to MAXITEMS rows
int rows = 0, i;
FILE * stream = fopen("test.txt", "r");
// Read in rows and put first and second columns into struct,
// building up an array
while (fscanf(stream, "%d %s", &(arr[rows].col1), arr[rows].col2) !=EOF) {
rows++;
}
// Sort the array using the rowcmp function to compare items
qsort(&arr[0], rows, sizeof(struct row), (__compar_fn_t)rowcmp);
fclose(stream);
// Print the sorted array
for (i=0; i<rows; i++) {
printf("%d\t%s\n", arr[i].col1, arr[i].col2);
}
}
With input file:
1 apple
3 cucumbers
21 dates
7 figs
4 grapes
output is
1 apple
3 cucumbers
4 grapes
7 figs
21 dates

give me a hand to understand this code

i have to write a c code that finds minimum of an array using recursion.i found this in the internet, but i don't understand it very well, can someone help me understand it?
#include <stdio.h>
int a[100],i;
void read(int i,int n)
{
if(i>=n)
return;
printf("element %d",i);
scanf("%d",&a[i]);
read(i+1,n);
}
int rec(int a[],int n)
{
int min;
if(n==1)
return a[0];
else {
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];
}
}
void main()
{
int i,j,n,a[100];
printf("enter n :");
scanf("%d",&n);
read(0,n);
printf("\n%d",rec(a,n));
getch();
}
if n=1, then min. is a[0] as there is only one element.
if n>1, then it is calling rec with the array and n-1 as the length each time. So, there will be a time when n=1 and returns a[0]. Then it will compare a[0] with a[1]. And return the minimum. Then it will compare the returned value minimum with a[2] and return the smaller value....and so on.
It calculates the minimal value in the array. Look at it that way:
Suppose you're given an array with 10 numbers. A magician tells you the the minimal value of that last 9 elements is 5. You now take the first element and compare it to 5. if it's smaller you return it, otherwise you return 5. The magician is the recursive call to the array with the last n-1 numbers.
rec(a, n) return the minimum value in {a[0], ..., a[n-1]}
Now we discuss two cases:
If n = 1, then rec(a,n) should be a[0], since there is only one value
Otherwise, rec(a,n) should be the minimum value of rec(a,n-1) (that is, the minimum value in {a[0],..,a[n-2]}) and a[n-1], which is what the following code do:
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];
int rec(int a[],int n)
{
int min;
if(n==1)
return a[0];
else {
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];
}
}
This function will go through all of your array elements, then compare them one by one, and each time return the smaller one, giving you the minimum of your array :
example : for a = {10,2,4,5}
rec will start from 5 and just calls itself with the previous elem until he's at the first : 10
then will return 10
will compare 10 with 2 and return 2 because 2 < 10
will compare 2 with 4 and return 2 because 2 < 4
will compare 2 with 5 and return 2 because 2 < 5
This program reads a size of an array the user wants to input, next it calls "read" which reads array elements of the given size recursively and fills in global array "a". Next it tries to find a minimal value of the local "a" array using recursive function "rec", that is initialized with garbage by the fact of being of "auto" variable type and types this value to the terminal screen. Next it waits for the user to type any character.

How to correctly compare and print out matching elements in this array in C?

I have this simple problem to which I am trying to write a solution, in C.
If an array arr contains n elements, then write a program to check
if arr[0] = arr[n-1], arr[1] = arr[n-2] and so on.
And my code looks like this-
#include<stdio.h>
int main()
{
int arr[10],i=0,j;
int k=0;
printf("\n Enter 10 positive integers: \n");
for(k=0;k<=9;k++)
scanf("%d",&arr[k]);
while(i<=9)
{
for(j=9;j>=0;j--)
{
if(arr[i]==arr[j])
{
printf("\n The array element %d is equal to array element %d\n", arr[i],arr[j]);
}
i++;
continue;
}
}
return 0;
}
On entering this input-
Enter 10 positive integers:
10
20
30
40
50
60
40
80
20
90
The output I get is-
The array element 20 is equal to array element 20
The array element 40 is equal to array element 40
The array element 40 is equal to array element 40
The array element 20 is equal to array element 20
Now, there are two problems with this code-
As you can see, the program prints out matching array elements twice. This is because, the way I've structured the program, once the variable i loops through the array from the first to last element, and then j loops through from the last to first element. So each prints out the matching array element once, leading to two sets of values.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
I've read that, in C, array dimensions(when declaring) cannot be a variable. So, a declaration like this(which was my first thought) wouldn't work-
int n; // n is no. of elements entered by the user
int arr[n];
I'm a newbie to programming, so my apologies if the question sounds/is too simple, low-quality.
Thank You.
1)You can traverse the array for half times for getting the prints only once. Instead of for(j=9;j>=0;j--) you can use for(j=9;j>=9/2;j--).
2)
int n;
int arr[n].
Recent Compilers support this statement. If you don't like to use this, you can go for dynamic memory allocation for the array.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
Use dynamic memory allocation. Use malloc().
So code will be
{
int num_elements;
int* arr;
printf("Enter number of elements\n");
scanf("%d", &num_elements);
arr = (int *) malloc(num_elements * sizeof(int)); // Use this 'arr' for holding input data from user
// Your remaining code comes here
free(arr); // Free the pointer in the end of program
}
the variable length creation works for me:
#include<stdio.h>
int main(){
int a, i;
scanf("%i", &a);
int blah[a];
for (i = 0; i < a; i++){
printf("/n%i", blah[a]);
}
}
The other way would be to create the maximum length array and than simply use first n elements.
As the previous answer states it is up to you to make sure you are checking each element only once therefore stopping at the element n/2. It is probably important that n/2 is rounded to the closest smaller integer, so at first glance odd numbers of arguments may be differently handled. But as it is omitting only the middle element it is identical to itself.
For your first query
for(i=0;i<n/2;i++)
{
if(a[i]==a[n-(i+1)])
{
printf("\n The array element %d is equal to array element %d\n",a[i],a[n-(i+1)]);
}
}
For your second query you can use condition i<(n/2) (which runs the loop (n/2)-1 times) For your case where n = 10 it will run from 0 to 4.
If you want to loop from 0 to 9 you can use
for(i=0;i<n;i++)
For making array of n elements where n is a variable either make an array of elements that is always greater than n or do it by making a dynamic array.
http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html
corrected:
#include<stdio.h>
int main()
{
int i=0, size; // size of array
int k=0; // counter
printf("enter size of array\n");
scanf("%d", &size); // ask user for desired size
int *arr = malloc(size * sizeof(int)); // allocate memory for array
printf("\n Enter 10 positive integers: \n"); // fill your array of size size
for(k=0;k<size;k++)
scanf("%d",&arr[k]);
k = 0; // reset this counter
for(i=0; i<size/2; i++) // check only for half of it
{
if(arr[i] == arr[size-i-1]) // try it with paper and pincil
{
printf("match arr[%d]=arr[%d]=%d\n", i,size-i-1, arr[i]);
k++;
}
}
if(k==0) printf("No matching");
return 0;
}

Resources