Matrix determinant .Bad output - c

When I try to calculate a 3-order determinant of a matrix ,I received bad outputs. At the 2-order one ,it work fine. To be more specific, I don't receive 9 values (v[1,1],v[1,2] etc) ,but instead i receive more than that. I thought is a problem to arrays ,but idk..
Code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void main(void) {
int i,j,n,i_max,j_max,ordin,i_m,j_m;
long int det;
int v[3][3];
int e[3];
int nr=0;
printf("\nIntroduceti ordinul matricei:\t");
scanf("%d",&n);
if (n==2) {
i_max=n;
j_max=n;
printf("\nIntroduceti valorile matricei:\n");
for (i=1;i<=i_max;i++) {
for (j=1;j<=j_max;j++) {
printf("v[%d,%d]= ",i,j);
scanf("%d",&(v[i][j]));
nr++;
e[nr] = v[i][j];
}
}
det = (e[1]*e[4])-(e[2]*e[3]);
printf("\nDeterminantul matricei este: %ld\n",det);
if (det != 0)
printf("Matricea de ordinul %d este inversabila !",n);
else printf("Matricea de ordinul %d nu este inversabila!",n);
} else if (n==3) {
i_m=n;
j_m=n;
printf("\nIntroduceti valorile matricei:\n");
for (i=1; i<= i_m; i++) {
for (j=1; j<= j_m; j++) {
printf("v[%d,%d]= ",i,j);
scanf("%d",&(v[i][j]));
nr++;
e[nr] = v[i][j];
}
}
det = (e[1]*e[5]*e[9])+(e[2]*e[6]*e[7])+(e[3]*e[4]*e[8])-(e[3]*e[5]*e[7])-(e[2]*e[4]*e[9])-(e[1]*e[6]*e[8]);
printf("Determinantul matricei este: %ld\n",det);
if (det != 0)
printf("Matricea de ordinul %d este inversabila!",n);
else
printf("Matricea de ordinul %d nu este inversabila!",n);
} else
printf("Ordinul matricei este incorect!");
return 0;
}

First, you declare
int v[3][3];
int e[3];
There are not enough items for e as you use it for v which has 3 x 3 = 9 elements.
So it seems that it would be solved by changing the second statement to
int e[9];
but it is not the end of story.
In the for loops you loop nor from 0 (which is common in C language), but from 1, so you need 1 more indices for all arrays!
So declare
int v[4][4]; /* for using indices from 1 to 3 */
int e[10]; /* for using indices from 1 to 9 */

First you say int v[3][3]; and int e[3]; and then you reach for elements like v[3][3] and e[4]. You seem to forget that arrays/matrices use 0-based indices. In other words, if you declare int v[3][3]; the only elements you should refer to are v[0][0]...v[2][2]. When reading data into v the for loops should go from 0 to 2, not from 1 to 3. Also, you clearly get out of the bounds of e, since it has 3 elements, but you go as far as e[9].
Btw, you also do not need to transfer things from v to e. After reading into v you can simply refer to v[0][0] as v[0], to v[0][1] as v[1], to v[1][0] as v[3] and to v[2][2] as v[8].
Also, you make pretty much the same errors in the part referring to the second order determinant.

Related

How can i remove this value on my random function in C language please? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 days ago.
Improve this question
i'm a beginner in C language and i want to create a black jack for a project and i did a little code that works but i have a problem.
If i remove the "-8" in the function "void sharing_cards", during the display, the last value is 8 and i don't know why and how remove it.
int randint(int a, int b) { // Fonction qui génère un entier dans un intervalle [a,b[
if ( a >= b ) {
return a;
} else {
return rand()%(b-a) + a ;
}
}
int deckrandom(int a[]) { // Fonction qui génère des nombres aléatoires dans un tableau
int x = 2;
int y = 9;
int z[8] = {randint(x,y), randint(x,y)};
int i;
for(i = 0; i < 8; i++)
printf("[%d]\n",z[i]);
}
void sharing_cards() { //Distribution initiale des cartes pour chaque joueur
int deckA[8];
int deckB[8];
int deck1= deckrandom(deckA); // Chercher la raison pour laquelle sans le "-8", l'affichage se fait avec [8]
printf("[%d]\n\n",deck1-8);
int deck2= deckrandom(deckB);
printf("[%d]\n\n",deck2-8);
}
int main () {
srand(time(NULL));
sharing_cards();
return 0;
}
The only solution i found is to soustract 8 ( lol ), but i want know how this problem appeared and how resolve it.
Thanks you!
deskrandom() is declared to return an int but doesn't. This means your code has undefined behavior. You haven't told us what the function should return so we cannot help you with that part (yet). Meanwhile I reworked your code:
Added missing header files.
Use constants instead of magic values. You may want to rename them so they make the most sense for your problem.
(not fixed) randint(): Consider treating a >= b as an error instead of degrading to predictable values.
deskrandom() now returns the randomized deck, and I changed the signature so your intention that you only want the first two elements set to random values and the remaining 6 are 0. If I didn't care about the last 6 values then I wouldn't even initialize them so just leave out the n_zero parameter.
deskrandom() no longer prints the deck as it's unrelated functionality, instead a new function was added to to that. As there is no point of printing static values it takes a count so you only print the first 2 values of each deck.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define CARDS 8
#define CARDS_BEGIN 2
#define DECKS 2
#define RAND 2, 9
int randint(int a, int b) {
return a >= b ? a : rand() % (b - a) + a;
}
void deckrandom(size_t n_random, size_t n_zero, int a[n_random + n_zero]) {
for(size_t i = 0; i < n_random + n_zero; i++)
a[i] = i < n_random ? randint(RAND) : 0;
}
void deckprint(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
printf("[%d]\n", a[i]);
}
void sharing_cards() {
int decks[DECKS][CARDS];
for(size_t i = 0; i < sizeof decks / sizeof *decks; i++) {
deckrandom(CARDS_BEGIN, CARDS - CARDS_BEGIN, decks[i]);
deckprint(CARDS_BEGIN, decks[i]);
}
}
int main () {
srand(time(NULL));
sharing_cards();
}

Modified Fibonacci in C

I need to generate a modified Fibonacci series and it must be completely dynamic. Here f0 and f1 will be given, i.e f0=1 and f1=3 after generating the series. I should print the resulting value at a particular index.
Ex: f0 = 1, f1 = 3, testcase(n) = 3 (This can change not a particular value)
t1 = 4 t2 = 8 t3 = 11 and so on. Series should be generated for 11 elements by adding current element and previous element using: f[i] = f[i-1] + f[i-2]
It can be represented as:
0=>1
1=>3
2=>4
3=>7
4=>11
5=>18
6=>29
7=>47
8=>76
9=>123
10=>199
11=>322
I should print the values at indices 4,8 and 11 (which must be the output of my program), i.e. 11 76 322.
Input Format:
f0,f1 and n (where n is the no of indices)
where ti=[t1,t2,....tn-1] (which specifies the index for R-Fibonacci series).
Output Format:
Print the values from the R-fibonacci series based on the given indices.
Sample Input:
1 3 3 4 8 11
Sample Output:
11 76 322
I have the code that generates the Fibonacci series for the above program but I want to display the value at 4,8,11 indices. Here is the code:
int fib(int n)
{
int f[n+1];
int i;
f[0]=1;
f[1]=3;
for(i=2;i<=n;i++)
{
f[i]=f[i-1]+f[i-2];
}
return f[n];
}
int main()
{
int n=11
printf("%d ",fib(n));
getchar();
return 0;
}
Like this? The array is defined in main and passed to the function as an argument. The function fills in the array, returns nothing, and then in main you can print the elements you want.
You will need a loop to do that, with another dynamic array holding the indices you are asked to print.
#include <stdio.h>
void fib(int n, int *f)
{
int i;
f[0] = 1;
f[1] = 3;
for(i = 2; i <= n; i++)
{
f[i] = f[i-1] + f[i-2];
}
}
int main()
{
int n = 11;
int f[n+1];
fib(n, f);
printf("%d ", f[8]);
printf("%d ", f[11]);
printf("\n");
getchar();
return 0;
}
Program output:
76 322
I will leave you some code to write, but suppose you make a dynamic array of the index values required, such as
int index[m];
index[0] = 4;
index[1] = 8;
index[2] = 11;
you can print the series term with such as
printf("%d ", f[ index[i] ]);
If I understand correctly, this question really has little to do with fibonacci and is about scope in C. You are declaring and defining an array in a function, fib, and filling it within that function (and returning a single element value). What you want is to have access to the entire array from the caller.
A straightforward way of doing this is to declare the array in the calling method, and pass a pointer to it to the fib function:
#include <stdio.h>
int fib(int f[], int n)
{
int i;
f[0]=1;
f[1]=3;
for(i=2;i<=n;i++)
{
f[i]=f[i-1]+f[i-2];
}
return f[n];
}
int main()
{
int n=11;
int f[12];
fib(f, n);
printf("%d ", f[4]);
printf("%d ", f[8]);
printf("%d ", f[11]);
getchar();
return 0;
}
Here is a code to generate a set of fibonacci numbers less than a given number N using recursive algorithm :
#include<stdio.h>
int fibo(int n)
{
if(n<2)
return n;
else
return (fibo(n-1)+fibo(n-2));
}
void main()
{
int n,i;
printf("\n Enter number : ");
scanf("%d",&n);
printf("\n Fibonacci series is : ");
for(i=0;i<n;i++)
printf("\n %d",fibo(i));
}

Transfering a 2-dimensional array into a single dimension array

I'm trying to make a program in C that transfers a 2-dimensions-array(a matrix to be particular) into a single-dimension-array. For example, if we have a matrix with L lines and C columns, it should turn into a a single line newL=L*C. Therefore, if the matrix has 3 lines and 4 columns, the new array will have 3*4=12 as its size.
The matrix should turn to this:
1 2
--> 1 2 3 4
3 4
The problem I'm facing right now, is how to assign the matrix to the array without having random values or repeated values.
The piece of code I'm concerned with, goes like this:
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
k,i and j are counters of the matrix(2-dimensions-array) and the the array. two of which; i and j, are counters for the matrix and k is the array's counter. Notice that each one of them starts from 1 and goes to its size and in this size I will use 2 lines and 2 columns for the matrix therefore the array will have a size of 4(2*2).
l is the number of lines in the array.
c is the number of colunms in the array.
t is the size of the array. t=l*c
Executing the code gives me this as a return:
1 2
--> 4 4 4 4
3 4
Simply said, the piece of code will ALWAYS give the last value of the matrix to the array. So if I replace 4 with 5 in the matrix, the array will have 5 5 5 5.
EDIT:
Here is the full code to understand what I'm trying to do:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
Thank you guys for the help, I found the correct way to do it.
You need not the outer loop
Array indices are zero-based in C
Thus, we have:
for(k = 0, i = 0; i < o; i++)
{
for(j = 0; j < p; j++)
{
v[k++] = m[i][j];
}
}
where o and p - dimensions of the matrix m
If we have a multidimensional array like this:
int nums[3][3];
And we have:
int all[9];
And we've got:
int a, b;
We'll reference each of the nums like this:
nums[a][b];
Now think of what the values of a and b will actually be:
for (a = 0; a < 3; a++) {
for (b = 0; b < 3; b++)
all[((a * 3) + b)] = nums[a][b];
}
This will work so long as you multiply a with the number of elements it will iterate:
int nums[5][5];
int all[25];
int a, b;
for (a = 0; a < 5; a++) {
for (b = 0; b < 5; b++)
all[((a * 5) + b)] = nums[a][b];
}
You mention your question is "how to I fix the code?" I think plenty of people have given you the correct answer. This is your code along with the corrected code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
/* corrected code below */
k = 0;
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
v[k]=m[i][j];
k++;
}
}
/* corrected code above */
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
As long as the new array is the correct size, something like the following should work:
k=0;
for(i=0;i<l;i++){
for(j=0;j<c;j++){
v[k]=m[i][j];
k++;
}
}
Essentially, you are traversing over the matrix (your lines and columns--as you put it) and at the same time increasing the position (k) in the new array where you want that value to be put.
This:
for(k=1;k<=t;k++)
for(i=1;i<=l;i++)
for(j=1;j<=c;j++)
v[k]=m[i][j];
does not do what you think. Think about when you first loop through the j part, you will be setting all the 0th element of v the entire time, finally the last value you set will stick (ie, the one in position 1, 1 which happens to be 4). Then you will increment k to 1 and repeat it again, resulting in all 4's. You want this:
for(i = 0; i < l; i++)
for(j = 0; j < c; j++)
v[i*l+j] = m[i][j]; // i*l + j gives you the equivelent position in a 1D vector.
Make sure your v vector is the right size ie. int v[l*c];. Also remember that in c zero indexing is used.If you really do need 1 based indexing (which you dont ...) then do this:
int k = 1;
for(i = 1; i <= l; i++)
for(j = 1; j <= c; j++)
v[k++]=m[i][j];
But remember that this will make any further operations on this vector Gross. So dont do this ....
If you just want to access the matrix elements as a single dimension array, you could declare an int pointer v:
int m[3][4];
int *v = (int*)m;
// then access for example m[1][1] as v[5]
Or, to actually copy the array, use a double for (as in the other answers), a single for like below
int vv[12];
for(i = 0; i < 12; i++)
vv[i] = m[i/4][i%4];
or just use memcpy:
memcpy(vv, m, 12*sizeof(int));

C factorial Table (1!-5!) Using For Loop

This my first post on here. I'd like to ask about a problem that I am trying to do for homework.
I'm supposed to be constructing a for loop for the "first 5 factorials" and display results as a table. I followed an example in the book, and I have my for loop and my operations set up, but I don't know what to do to produce the loop in the table. Here is my program:
#include <stdio.h>
int main(void) {
//Problem: Display a range for a table from n and n^2, for integers ranging from 1-10.
int n, factorialnumber, i;
printf("TABLE OF FACTORIALS\n");
printf("n n!\n");
printf("--- -----\n");
for (n = 1; n <= 10; n++) {
factorialnumber = factorialnumber * n;
printf("\n %i = %i", factorialnumber, n);
}
return 0;
}
I know the printf here is wrong. What would I type?
BTW, I'm using codeblocks.
The problem is that you didn't initialize the variables (e.g. factorialnumber). If it has an initial value of 6984857 let's say, the whole algorithm would be messed up.
Try this :
#include <stdio.h>
int main(void) {
//Problem: Display a range for a table from n and n^2, for integers ranging from 1-10.
int i, factorialnumber = 1;
int n = 10; // Max number to go through
printf("TABLE OF FACTORIALS\n");
printf("i i!\n");
printf("--- -----\n");
for (i = 1; i <= n; i++) {
factorialnumber *= i;
printf("%d! = %d\n", i, factorialnumber);
}
return 0;
}

I don't get all the values of my (int) array from Selection Sort algorithm

I'm programming on Ubuntu 14.04 using the gcc compiler.
I am using the rand(); function to give values to the elements of my array.
( rand() % 101; actually, so I don't get values higher than 100 )
Then I want to sort the elements of my array using the 'Selection sort' algorithm, but when I print(f) them out, the first two elements are 0's, even though there are no 0's on my array (most of the time).
Here's my code, please review it, compile it, try it out and guide me:
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, j, tam_arreglo;
time_t t;
int *a;
int aux;
/* Here I'm asking for you to give me the size of the array and store it in tam_arreglo */
printf("Introduzca el tamaño del arreglo: \n");
scanf("%d",&tam_arreglo);
/* Making my array the size I just asked you */
int array[tam_arreglo];
srand((unsigned) time(&t));
/* Dynamic random filling of the array */
printf("El arreglo sin ordenar es: \n");
a = malloc(tam_arreglo * sizeof(int));
for(i = 0 ; i < tam_arreglo ; i++) {
a[i] = rand()%101;
printf("%d\n", a[i]);
}
free(a);
/* My 'Selection sort' algorithm */
for(i = 0; i < tam_arreglo; i++) {
for(j = i+1; j < tam_arreglo; j++) {
if(a[i] > a[j]) {
aux = a[i];
a[i] = a[j];
a[j] = aux;
}
}
}
/* Here's when I get the error, the first two elements printed are 0's */
printf("El arreglo ordenado es: \n");
for(i = 0; i < tam_arreglo; i++) {
printf("%d\n", a[i]);
}
return(0);
}
What am I doing wrong?
You should not free() the array yet, when you will no longer access the memory pointed to buy the pointer, then you call free() but never before.
When you access the a pointer in the code following free(a); there will be garbage because the memory was free()'d already.
So, move free(a) after the second for loop just before return and it should work well.
And also, you don't need to use parentheses with return, and check the value returned by scanf() in case of invalid input, since in that case tam_arreglo will be uninitialized and your program will invoke undefined behavior.

Resources