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.
Related
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'
I am currently working on a simple code to store and display top-right triangular matrix. Well, everything was fine till I tried to input 4x4 matrix structure and gave the input. The first array of structure's (called a) last value changed although I did not put any code to change ANY of the values in a. It happens in the mReorder() function. Then I tried some try-and-errors find out the problem in the 3rd row of mReorder() function. I wonder why and how to solve it.
Here is my complete code:
#include<stdio.h>
//CMO fashion
typedef struct
{
int row;
int col;
int val;
}term;
#define MAX_TERMS 10
term a[MAX_TERMS], b[MAX_TERMS];
void mReorder(void);
int main()
{
int n, i, j;
printf("Enter the number of rows: ");
scanf("%d", &n);
if (n<1 || n>MAX_TERMS)
{
printf("\nInvalid number of rows!!");
exit(0);
}
i=nCount(n);
mRead(n,i);
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
mReorder();
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
printf("\n");
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", b[j].col, b[j].row, b[j].val);
mDisplay();
return 0;
}
void mReorder(void)
{
int i, j, k, m=1;
b[0].col=a[0].col;
b[0].row=a[0].row;
b[0].val=a[0].val;
for(i=0; i<a[0].col; i++)
for (j=1; j<=a[0].val; j++)
if (a[j].row==i)
{
b[m].col=a[j].col;
b[m].row=a[j].row;
b[m].val=a[j].val;
m++;
}
}
void mDisplay(void)
{
int i, j, k, m=1;
printf("\nThe resulting matrix is:\n");
for (i=0; i<b[0].col; i++)
{
//printf("\na");
for (k=0; k<i; k++) printf("%5c", '-');
for (j=i; j<b[0].col; j++)
{
printf("%5d", b[m].val);
m++;
}
printf("\n");
}
}
void mRead(int n, int x)
{
int i, j, m=1, val;
printf("\nEnter %d elements of the matrix: \n", x);
a[0].row=a[0].col=n;
a[0].val=x;
for (i=0; i<n; i++)
{
for (j=0; j<=i; j++)
{
scanf("%d", &val);
a[m].row=j;
a[m].col=i;
a[m].val=val;
m++;
}
}
}
int nCount(int n)
{
if (n==1)
return 1;
return (n+nCount(n-1));
}
Can you explain what's going on here?
You allocate enough space for 10 term items, but nCount(4) returns 10, and nCount(5) returns 15, etc. If you specify a value bigger than 4, you overflow your array boundaries, leading to undefined behaviour — which is something to be avoided at all costs. In practice, one of your two arrays tramples over the other, but what happens when you access the other array out of bounds is entirely up to the compiler. It may appear to work; it may crash horribly; it may corrupt other data structures.
Nominally, since you allocate 10 elements in the arrays a and b, you should be OK with the 4x4 data, but in mRead(), you set m = 1 to start with, so you end up writing to a[10] in the last iteration of the loop, which is outside the bounds of the array. Remember, C arrays are indexed from 0, so an array defined as SomeType array[N]; has elements from array[0] to array[N-1].
Note that you can rewrite nCount() as a simple (non-recursive) function:
static inline int nCount(int n) { return (n + 1) * n / 2; }
(which would need to appear before it is called, of course). Or, if you're stuck using an archaic compiler that doesn't support C99 or C11, drop the inline keyword.
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.
So all I'm trying to do is take an input from the user of how many cards to use and then randomly assign each card to a different index in an array. I'm having extensive issues getting the rand function to work properly. I've done enough reading to find multiple different ways of shuffling elements in an array to find this one to be the easiest in regards to avoiding duplicates. I'm using GCC and after I input the amount of cards I never get the values from the array back and if I do they're all obscenely large numbers. Any help would be appreciated.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
void main(){
srand(time(NULL));
int d, c, i, z, l, r;
printf("Enter the deck length: ");
scanf("%d\n ", &c);
int deck[c];
int swap[c];
z = c;
for(l=0; l<c; l++){
swap[l] = l;
}
for(i=z; i=0; i--){
r = rand() / i
deck[i] = swap[r];
for(r; r=(c-1); r++){
swap[r] = swap[(r+1)];
}
}
for(d = 0; d < c; d++){
printf("%d ", deck[d]);
}
return;
}
I can spot one major problem here:
for(i=z; i=0; i--)
^^^
This loop will never execute since you are using assignment(=) and setting i to 0 therefore the condition will always be false, although using equality(==) will still be false in this case, you probably want:
for(i=z; i!=0; i--)
This means you will be using deck unitialized which is undefined behavior. Once you fix that you have a similar problems here:
for(r; r=(c-1); r++){
main has to return int and your return at the end needs to provide a value.
Turning on warning should have allowed you to find most of these issues, for example using -Wall with gcc gives me the following warning for both for loops:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Note, see How can I get random integers in a certain range? for guidelines on how to use rand properly.
You basically need to be able to generate 52 numbers pseudo-randomly, without repeating. Here is a way to do that...
First, loop a random number generator 52 times, with a method to ensure none of the random numbers repeat. Two functions in addition to the main() will help to do this:
#include <ansi_c.h>
int NotUsedRecently (int number);
int randomGenerator(int min, int max);
int main(void)
{
int i;
for(i=0;i<52;i++)
{
printf("Card %d :%d\n",i+1, randomGenerator(1, 52));
}
getchar();
return 0;
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
while(trying)
{
srand(clock());
random = (rand()/32767.0)*(max+1);
((random >= min)&&(NotUsedRecently(random))) ? (trying = 0) : (trying = 1);
}
return random;
}
int NotUsedRecently (int number)
{
static int recent[1000];//make sure this index is at least > the number of values in array you are trying to fill
int i,j;
int notUsed = 1;
for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++) (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0])));
if(notUsed)
{
for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--)
{
recent[j-1] = recent[j-2];
}
recent[j-1] = number;
}
return notUsed;
}
I have currently learning backtracking and got stuck on the 8-queen problem, I am using a 8x8 matrix and I think I've got some problems regarding the matrix passing to functions, any help would be highly apreciated.I wouldn't mind if anyone would bring any optimisation to the code, thanks.
here is my code.
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
//void azzera(int **mat);
void posiziona(int **mat, int r,int c);
void stampa(int **mat);
int in_scacchi(int **mat,int r ,int c);
int main(int argc, char *argv[])
{
int i=0,j=0;
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
printf("insert pos of the first queen on the first row (1-8) :");
scanf("%d",&i);
i-=1;
mat[0][i]=1;
posiziona(mat,1,0);
stampa(mat);
system("PAUSE");
return 0;
}
/*void azzera(int **mat){
int i=0,j=0;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
}*/
void stampa(int **mat){
int i,j;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
printf(" %d",mat[i][j]);
}
printf("\n");
}
}
void posiziona(int **mat, int r,int c){
int i=0,riga=1,flag_col=-1,flag_riga=-1;
if(riga<=7&&flag_riga!=1){
if(flag_riga==1){
flag_riga=-1;
posiziona(mat,r+1,0);
}
else if(in_scacchi(mat,r,c)==1){
if(c==MAX)
posiziona(mat,r-1,0);
posiziona(mat,r,c+1);
}
else{
flag_riga=1;
}
}
}
int in_scacchi(int **mat,int r ,int c){
int i,j,k,m;
int flag=0;
//col
for(i=0;i<r;i++){
for(j=0;j<=c;j++){
if(((mat[i][j]==1)&&(c==j)))
return 1;
}
}
//diag \
for(i=0;i<MAX-r;i++){
for(j=0;j<=MAX-c;j++){
if(mat[MAX-r-i][MAX-c-j]==1)
return 1;
}
}
//antidiag
for(i=r+1;i<=MAX;i++){
for(j=c+1;j<=MAX;j++){
if(mat[r-i][c+j]==1) {
return 1;
}
}
}
return 0;
}
1. One glaring problem is the memory allocation:
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
Given that MAX is 7, both mallocs are allocating too little memory for the matrix (seven elements instead of eight).
To be honest, I'd rename MAX to SIZE or something similar, and change all your loops to use strict less-than, i.e.
for(i = 0; i < SIZE; i++) {
I would argue that this is slightly more idiomatic and less prone to errors.
2. I haven't tried to debug the logic (I don't think it's fair to expect us to do that). However, I have noticed that nowhere except in main do you assign to elements of mat. To me this suggests that the code can't possibly be correct.
3. Beyond that, it may be useful to observe that in a valid solution every row of the chessboard contains exactly one queen. This means that you don't really need an 8x8 matrix to represent the solution: an 8-element array of column positions will do.
edit In response to your question in the comments, here is a complete Python implementation demonstrating point 3 above:
def can_place(col_positions, col):
row = len(col_positions)
for r, c in enumerate(col_positions):
if c == col or abs(c - col) == abs(r - row): return False
return True
def queens(n, col_positions = []):
if len(col_positions) >= n:
pretty_print(n, col_positions)
return True
for col in xrange(n):
if can_place(col_positions, col):
if queens(n, col_positions + [col]):
return True
return False
def pretty_print(n, col_positions):
for col in col_positions:
print '.' * col + 'X' + '.' * (n - 1 - col)
queens(8)
Your matrix must iterate from 0 to MAX-1,
i.e
int **mat= malloc(sizeof(int *)*MAX);
for(i=0;i< MAX;i++){ //see for i<MAX
mat[i]= malloc(MAX*sizeof(int));
for(j=0;j<MAX;j++){ //see for j<MAX
mat[i][j]=-1;
}
}
malloc must be called with sizeof(...) * (MAX+1) in both the i- and j-loop.
Moreover, when I ran your program I got an access violation in the antidiag portion of in_scacchi(...) due to the fact that the code tries to access mat[r-i][c+j] which evaluates to mat[-1][1] because r==1 and i==2.
So there seems to be a logical error in your description of the anti-diagonal of the matrix.