Last element during multiplication of sparse matrice not printing? - c

I have just started data structures and I was practicing multiplication of sparse matrice via triplet representation. My code was:
#include<stdio.h>
#include<stdlib.h>
void main(){
int smatrix1[4][3]={{1,2,10},{1,3,12},{2,1,1},{2,3,2}};
int smatrix2[4][3]={{1,1,2},{1,3,8},{2,1,5},{2,2,1}};
int i,j,x=0;
int smatrix3[4][4];
for(int i=0;i<4;){
int r=smatrix1[i][0];
for(int j=0;j<4;j++){
int c=smatrix2[j][0];
int tempa=i,tempb=j;
int sum=0;
while(tempa<=4 && smatrix1[tempa][0]==r && tempb<=4 && smatrix2[tempb][0]==c){
if(smatrix1[tempa][1]<smatrix2[tempb][1])
tempa++;
else if(smatrix1[tempa][1]>smatrix2[tempb][1])
tempb++;
else if(smatrix1[tempa][1]==smatrix2[tempb][1])
sum+=smatrix1[tempa++][2]*smatrix2[tempb++][2];
printf("%d\n",sum);
}
printf("R C SUM %d%d%d\n",r,c,sum);
if(sum!=0){
smatrix3[x][0]=r;
smatrix3[x][1]=c;
smatrix3[x][2]=sum;
x++;
}
while(j<=4 && smatrix2[j][0]==c)
j++;
}
while(i<=4 && smatrix1[i][0]==r)
i++;
}
for(int i=0;i<4;i++){
printf("%d\t%d\t%d\n",smatrix3[i][0],smatrix3[i][1],smatrix3[i][2]);
}
}
While all the elements are printing correctly, the last element results in garbage value. I tried to dry run it but same result. Can anyone please tell me the reason as well as solution?
Edit: I added <=4 instead of <4 incase last element was ignored due to postscript ++ operator. Adding or removing = sign had no effect whatsoever.

EDIT: Here's your problem. This line should not being incrementing j:
Change:
for(int j=0;j<4;j++){
To:
for(int j=0;j<4;){
Also all the comparisons for '<= 4' should be '< 4'

Related

Getting an error only when two same odd numbers are adjacent in the array

THE PROBLEM
I am facing the problem when i was solving one of the leetcode question
Find Numbers with Even Number of Digits.
This is the code which i have written, the algorithm that i used here is using a for loop to iterate to all the array elements and then i declared the variables b=0 and l=10.then while using a while loop of condition (c!= nums[i]). The while loops happens until c(which is initialised it to nums[i]) is equal to array element.
then i check whether b%2==0 and increment integer ans
int findNumbers(int* nums, int numsSize){
int ans=0,c;
for (int i = 0; i < numsSize; ++i) {
int b=0,l=10;
while(c!=nums[i])
{
c=nums[i];
c=c%l;
l=l*10;
b++;
}
if(b%2==0 && nums[i]!=49916) {
ans++;
}
}
return ans;
}
If i take two odd digit numbers for suppose [78968,78968]. I am getting the output as 1 while the expected answer should be 0
Output for the above example
Excuse me if you had any difficulties understanding the questions. Learning to write better questions!
#include <stdio.h>
int findNumbers(int* nums, int numsSize){
int ans=0,c;
for (int i = 0; i < numsSize; ++i) {
int b=0,l=10;
c=0;
while(c!=nums[i])
{
c=nums[i];
c=c%l;
l=l*10;
b++;
}
if(b%2==0 && nums[i]!=49916)
{
ans++;
}
}
return ans;
}
int main()
{
int n[]={462,462};
printf("%d",findNumbers(n,2));
return 0;
}
This code should work for you. Actually the problem was when the loop was iterated first time the value of c will be 462 according to above code so while loop will not be iterated as c!=nums[i] will become false and value of b = 0 so if condition will become true so the value of ans will be incremented and you are getting answer as 1.

DP for 0-1 knapsack with two factors to optimize upon. Link - http://www.spoj.com/problems/SCUBADIV/

The problem is a 0-1 Knapsack and tries to minimize the output based on 2 constraint factors. Can somebody suggest whats wrong with the following code? Its giving WA.I am using a bottom-up approach.
Can somebody point out the test-cases where it fails?
#include<cstdio>
#include<climits>
using namespace std;
#define DEBUG 0
inline int min(int x, int y)
{
int p= (x<y?x:y);
return p;
}
int dp[1001][22][80];
int main()
{
int tc,o,n;
int num;
int ox[1000],nn[1000],wt[1000];
scanf("%d",&tc);
while(tc--){
scanf("%d %d",&o,&n);
scanf("%d",&num);
for(int i=1;i<=num;i++){
scanf("%d %d %d",ox+i,nn+i,wt+i);
}
//DP
for(int i=0;i<=o;i++){
for(int j=0;j<=n;j++){
dp[0][i][j]=INT_MAX;
}
}
dp[0][0][0]=0;
for(int items=1;items<=num;items++){
for(int oxygen=0;oxygen<=o;oxygen++){
for(int nitrogen=0;nitrogen<=n;nitrogen++){
if(oxygen>=ox[items] && nitrogen>=nn[items] && dp[items-1][oxygen-ox[items]][nitrogen-nn[items]]!=INT_MAX){
dp[items][oxygen][nitrogen]=min(dp[items-1][oxygen][nitrogen],(dp[items-1][oxygen-ox[items]][nitrogen-nn[items]]+wt[items]));
}
else if(oxygen>=ox[items] && nitrogen<nn[items] && dp[items-1][oxygen-ox[items]][0]!=INT_MAX){
dp[items][oxygen][nitrogen]=min(dp[items-1][oxygen][nitrogen],(dp[items-1][oxygen-ox[items]][0]+wt[items]));
}
else if(nitrogen>=nn[items] && oxygen<ox[items] && dp[items-1][0][nitrogen-nn[items]]!=INT_MAX){
dp[items][oxygen][nitrogen]=min(dp[items-1][oxygen][nitrogen],(dp[items-1][0][nitrogen-nn[items]]+wt[items]));
}
else if(oxygen<ox[items] && nitrogen<nn[items]){
dp[items][oxygen][nitrogen]=min(dp[items-1][oxygen][nitrogen],wt[items]);
}
else{
dp[items][oxygen][nitrogen]=INT_MAX;
}
#if DEBUG
printf("\ndp[%d][%d][%d]=%d",items,oxygen,nitrogen,dp[items][oxygen][nitrogen]);
#endif
}
}
}
printf("%d\n",dp[num][o][n]);
}
}
Your program will fail when n=1000 because you are using 1-based indexing for the test cases, and therefore you will be accessing elements beyond the ends of your arrays.
Solution: use 0-based indexing (best solution) or increase the array sizes to 1001 (ugly hack).
There may be other bugs too, but this one definitely needs to be fixed.

Using Malloc Arrays inside a for loop and an if statement in C - Leading to Segmentation

this is my first post, so sorry if it doesn't meet the standards in which I should post, if there are any issues with how I've placed the code just say and Ill take that into account for future posts. I tried to comment the code as much as possible, maybe a little too much.
So the idea of the code is to take a normal matrix in and then store it in reduced form, this works fine, but when I wish to also multiply this with with a vector it fails.
The code fails, since when I do the double for loop with an if statement it segments and I have no idea why.
It works fine if I specify the elements seperatly but then fails when I try to increment what elements it should select for Matrix_R when inside the if statement.
Any help would be greatly appreciated. Thanks !!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int i;
int j;
int n;
int m;
int k=0;
double * Vin;
double * Vout_M;
double * Vout_MR;
double ** Matrix;
double ** Matrix_R;
//Vout_M and Vout_MR are output vectors for the two possible inputted matricies
//Matrix_R is the reduced form of Matrix
n=4;
Vin = malloc(n*sizeof(double));
Vout_M = malloc(n*sizeof(double));
Vout_MR = malloc(n*sizeof(double));
Matrix = malloc(n*sizeof(double*));
for(i=0;i<n;i++)
Matrix[i] = malloc(n*sizeof(double));
//Allocates memory for the arrays
for(i=0;i<n;i++){
Vin[i]=1;
Vout_M[i]=0;
Vout_MR[i]=0;
}
//Initiates the vector arrays
for(i=0;i<n;i++)
for(j=0;j<n;j++)
Matrix[i][j]=0;
//Initiates the Matrix
Matrix[2][3]=5;
Matrix[0][2]=10;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(Matrix[i][j]!=0)
m++;
//Scans through to determine what size the reduced array should be
//In Future, this could be set up to read from a text file, and so RAM isn't used to store the array to find elements
Matrix_R = malloc(m*sizeof(double*));
for(i=0;i<m;i++)
Matrix_R[i] = malloc(3*sizeof(double));
for(i=0;i<m;i++)
for(j=0;j<3;j++)
Matrix_R[i][j]=0;
//Produces the reduced array, and initiates it
printf("\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(Matrix[i][j]!=0){
Matrix_R[k][0]=Matrix[i][j];
Matrix_R[k][1]=i;
Matrix_R[k][2]=j;
k++;
}
//Scans through the Matrix array and outputs to the Matrix_R array
for(i=0;i<k;i++)
printf("Matrix_R[%d][0] = %lf, Matrix_R[%d][1] = %lf, Matrix_R[%d][2] = %lf\n",i,Matrix_R[i][0],i,Matrix_R[i][1],i,Matrix_R[i][2]);
//Checks if it is storred correctly -- this outputs fine
//Now first do the multiplication between the normal matrix and vector --- Matrix * Vector
for(i=0;i<n;i++)
for(j=0;j<n;j++)
Vout_M[i] += Matrix[i][j]*Vin[j];
for(i=0;i<n;i++)
printf("\nVout_M[%d] = %lf",i,Vout_M[i]);
printf("\n");
//Prints the output from a standard Matrix * Vin in the form of Vout_M
k=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
if(i == Matrix_R[k][1] && j == Matrix_R[k][2]){
Vout_MR[i] += Matrix_R[k][0]*Vin[j];
k++;
}}
//Goes through standard matrix-vector multiplication, using reduced matrix
//SEGMENTS :: When trying to go through an if statement and incrementing k.
//i.e. If I set k=int, and then not increase it in the if statement it works.
for(i=0;i<n;i++)
printf("\nVout_MR[%d] = %lf",i,Vout_MR[i]);
printf("\n");
//Outputs the Vout_MR which is from Matrix_R * VIN
free(Vin);
free(Vout_M);
free(Vout_MR);
for(i=0;i<n;i++)
free(Matrix[i]);
for(i=0;i<m;i++)
free(Matrix_R[i]);
return 0;
}
In your code, you never initialized
int m;
and you're using the value uninitialized in
if(Matrix[i][j]!=0)
m++;
and
Matrix_R = malloc(m*sizeof(double*));
It produces a read-before-write scenario. The behaviour is not defined.
Also, always check for the return value of malloc() to ensure success.
You can [and should] use %f format specifier to print double values. Change
printf("\nVout_M[%d] = %lf",i,Vout_M[i]);
to
printf("\nVout_M[%d] = %f",i,Vout_M[i]);
Next, you've free()d all the Matrix[i] and Matrix_R[i] but you forgot to free() Matrix and Matrix_R themselves.
EDIT
In your code, there is no boundary check for the value k in
if(i == Matrix_R[k][1] && j == Matrix_R[k][2])
Once your k >= m, you'll be accessing out-of-bound memory invoking undefined behaviour. A side effect is segmentation fault.
Most likely, in your case, m is having a value 2, and when k becomes 2 via k++, the next access to i == Matrix_R[k][1] generates out-of-bound memory access.
for(i=0;i<n;i++)
for(j=0;j<n;j++){
if(i == Matrix_R[k][1] && j == Matrix_R[k][2]){
Vout_MR[i] += Matrix_R[k][0]*Vin[j];
k++;
}}
Here you keep incrementing k and there is no guarantee k<m so as you keep incrementing k there is a access Matrix_R[k][1] where k>m leading to UB

Challenge C programming

What should I do so that the program run without any mistakes ..
#include <stdio.h>
int i= 0;
while (i< SIZE){
j= i+1;
while (j<SIZE){
if (myList[i]+ myList [j] == target){
printf("%d AND %d\n", i, j);
}
j= j+1;
}
i=i+1;
}
In order to compile and execute this code, you must type this into an editor. Make sure that all required variables are suitably declared. Also make sure that the values are input using scanf() prior to executing these if-else statements. If you run the compiler several times, it will help you to identify the variables that must be declared.
Question: Write a C program that will read in N=1000 integers, i1, i2, …, iN. These numbers are not sorted and you may assume that these integers also do not have any regular pattern. After reading these N integers, your program must now read in a new integer called the Target. Find all pairs of integers ij and ik from these N integers such that ij + ik = Target.
Well, I tried your code, and have got it to work. I am assuming that j can be equal to k. If they cannot be equal, then I have indicated which part is to be changed in the code ( There its i and j instead of j and k ). Well here's the fixed code
#include <stdio.h>
#define SIZE 10 // You can change SIZE here
int main()
{
int myList[SIZE],target;
printf("Enter 10 Numbers\n");
for(int k=0;k<SIZE;k++)
{
scanf("%d",&myList[k]);
}
printf("Enter the target\n");
scanf("%d",&target);
int i= 0,j;
while (i< SIZE)
{
j=i; // if i and j should not be equal just change it to j=i+1
while (j<SIZE)
{
if (myList[i]+ myList [j] == target)
{
printf("%d AND %d\n", i, j);
}
j= j+1;
}
i=i+1;
}
return 0;
}
In this code, I have taken SIZE=10 for convenience because I don't want to enter 1000 numbers. You can just change SIZE to 1000 whenever you want.
Cheers.......Hope this is what you wanted.

Matrix Multiplication in C language

I am trying to multiply 2 dimensional matrices in C language. I have furnished below the code for your reference. When I try to print 'myC', I keep getting zeros out. Where am i going wrong ? I've tried multiple things and still can not figure this out. Has anyone got ideas, that would be greatly appreciated.
#include <stdio.h>
#define mysize 4
int myA[mysize][mysize];
int myC[mysize][mysize];
int i,k;
int j,l;
int total;
int iLimit;
int jLimit;
void printMatrix(int iLimit,int jLimit,int myA[iLimit][jLimit]){
i=0;
while (i<iLimit){
j=0;
while (j<jLimit){
printf ("%7d", myA[i][j]);
j=j+1;
}
printf ("\n");
i=i+1;}
}
int main(void){
iLimit=mysize;
jLimit=mysize;
k=0;
while (k < iLimit){
l=0;
while (l < jLimit) {
scanf ("%d",&myA[k][l]);
l=l+1;
}
k=k+1;
}
printMatrix(mysize,mysize,myA);
myC[i][j]=myA[i][k]*myA[k][j];
printf("\n");
printMatrix(mysize,mysize,myC);
return 0;
}
the multiplication of the matrices has to be done for all the elements. so it should be in a nested for loop. what you are doing in your code
myC[i][j]=myA[i][k]*myA[k][j];
this statement would multiply only one element of the matrix that is represented by the index i,j,k (out of bound in your code). the above statement has to be kept inside 3 nested for loops. something like this..
for (i=0;i<m;i++)
{
for(j=0;j<q;j++)
{
myC[i][j]=0;
for(k=0;k<n;k++)
myC[i][j]+= myA[i][k]*myA[k][j];
}
}
This only multiplies two elements, where i j and k are all out of bounds.
myC[i][j]=myA[i][k]*myA[k][j];
It should be in a triple-loop, where you set i j and k appropriately.

Resources