Matice v C

Programovacie jazyky, rady, poradňa...
malinator
Novice
Novice
Používateľov profilový obrázok
Príspevky: 7
Registrovaný: 13 dec 2008, 16:47
Kontaktovať používateľa:

Matice v C

Príspevok od používateľa malinator »

Zdravim pani a damy, mam na vas prosbu. Dostali sme v skole zadanie - http://www.kaivt.elf.stuba.sk/kaivt/Pre ... c)/Zadania (Zadanie 1) a mam problem asi taky ze ked zadam 1. maticu tak je vsetko v pohode ale ked zadam druhu maticu tak ta prva je stratena posielam vam moj zdrojak...
POTREBUJEM DOROBIT DETERMINANT A INVERZNU MATICU :(

Kód: Vybrať všetko

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void vypisMaticu(int ***pole, int index, int rozmer);
void nacitajMaticu(int ***pole, int index, int rozmer);
void nasobMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer);
void scitajMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer);
void odcitajMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer);
int sum_hlav_diag(int ***pole, int index, int rozmer);
int Determinant(int ***pole, int index, int rozmer);

int main(int argc, char *argv[])
{
	int rozmer=2, ***pole = NULL, i, j, l_index, r_index, result_index;
	char operacia, l_operator, r_operator, result_operator, matica;
	int volba,vypis,n;

	pole = (int ***)malloc(sizeof(int **) * 26);													// AlOKACIA
	  for (i = 0 ;  i < 26; i++)	 {
		pole[i] = (int **)malloc(sizeof(int *) * rozmer);
		  for (j = 0; j < rozmer; j++)
			pole[i][j] = (int *)malloc(sizeof(int) * rozmer);	}

	do {
	printf("Volba:\n\n");
	printf("1. Nacitaj maticu z klavesnice\n");
	printf("2. Pocitaj matice\n");
	printf("3. Vypis maticu\n");
	printf("4. Determinant\n");
	printf("5. Koniec\n");
	scanf("%i", &volba);
	switch (volba)
	{
        case 1:
			    printf("Zadaj index matice (A-Z): \n");
				scanf("\n%c",&matica);
				n = (int)matica - 65;
				nacitajMaticu(pole,n,rozmer);
				break;
        case 2:
																							 		// ZADANIE OPERACIE
		   		printf("Zadaj operaciu (napr. A * B , A + B , A - B):\n");
				scanf("\n%c %c %c", &l_operator, &operacia, &r_operator);
				l_index = (int)l_operator - 65;
				r_index = (int)r_operator - 65;
				printf("Zadaj do ktorej matice sa ma uskutocnit zapis:\n");
				scanf("\n%c", &result_operator);
				result_index = (int)result_operator - 65;
																									// VYKONANIE
				switch (operacia)
				{
                    case '+': scitajMatice(pole,l_index,r_index,result_index,rozmer);
							  break;
                    case '*': nasobMatice(pole,l_index,r_index,result_index,rozmer);
						 	  break;
                    case '-': odcitajMatice(pole,l_index,r_index,result_index,rozmer);
                    	 	  break;
		             default: printf("Neznama operacia!!!\n");
			    }
			    break;
        case 3: printf("Zadaj index matice (A-Z): ");
        	 	scanf("\n%c",&matica);
				n = (int)matica - 65;
        	 	vypisMaticu(pole,n,rozmer);
				break;
        case 4: printf("Determinant matice (A-Z): \n");
				scanf("\n%c",&matica);
        	 	n = (int)matica - 65;
        	 	Determinant(pole,n,rozmer);
        	 	break;
        case 5: system("pause");
	 	 	 	return 0;
			 	break;
	   default: printf("Chyba!!!\n");

	}
    } while(volba != 5);

	system ("pause");
	return 0;
}

int sum_hlav_diag(int ***pole, int index, int rozmer)
{
	int i,j, x=0;
	for (i=1; i<rozmer; i++)
		for (j=i+1; j<rozmer; j++)
			if ( pole[index][i][j] != pole[index][j][i] ) x++;
	if (x) return 0;
	else return 1;
}

void scitajMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer)				// SCITANIE FUNGUJE DOBRE
{
	int i,j;
	for (i=0; i<rozmer; i++)
		for (j=0; j<rozmer; j++)
			pole[index_vysl][i][j] = pole[index_1][i][j] + pole[index_2][i][j];
}

void odcitajMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer)				// ODCITANIE FUNGUJE DOBRE
{
	int i,j;
	for (i=0; i<rozmer; i++)
		for (j=0; j<rozmer; j++)
			pole[index_vysl][i][j] = pole[index_1][i][j] - pole[index_2][i][j];
}

void nasobMatice(int ***pole, int index_1, int index_2, int index_vysl, int rozmer)					// NASOBENIE NEFUNGUJE
{
	int i,j,k;
	for (k=0; k<rozmer; k++)
		for (j=0; j<rozmer; j++)
			for (i=0; i<rozmer; i++)
				pole[index_vysl][k][j] += pole[index_1][k][i] * pole[index_2][i][j];
}

void nacitajMaticu(int ***pole, int index, int rozmer)
{
	int i,j;	
	char c = (char)(index + 65);
	printf("Zadaj maticu %c: ", c);
	printf("\n");
	for (i=0; i<rozmer; i++)
		for (j=0; j<rozmer; j++)
			scanf("%d", &pole[index][i][j]);
}

void vypisMaticu(int ***pole, int index, int rozmer)
{
	int i, j;
	char c = (char)(index + 65);
	printf("Matica %c:\n", c);
	for (i=0; i<rozmer; i++)
	{
		for (j=0; j<rozmer; j++)
			printf("%d\t", pole[index][i][j]);
			printf("\n");
	}
}

int Determinant(int ***pole, int index, int rozmer)													// VSTUPOM CHCEM ABY BOL INDEX MATICE (0-25) A ROZMER (TEN JE FIXNY)
{
   int i,j,j1,j2;
   int det = 0;
   int **m = NULL;
   char c = (char)(index + 65);

   if (rozmer < 1) {

   } else if (rozmer == 1) {
      det = pole[index][0][0];
   } else if (rozmer == 2) {
      det = pole[index][0][0] * pole[index][1][1] - pole[index][1][0] * pole[index][0][1];
   } else {
      det = 0;
      for (j1=0; j1<rozmer; j1++) {
         m = malloc((rozmer-1)*sizeof(int *));
         for (i=0; i<rozmer-1; i++)
            m[i] = malloc((rozmer-1)*sizeof(int));
         for (i=1;i<rozmer;i++) {
            j2 = 0;
            for (j=0;j<rozmer;j++) {
               if (j == j1)
                  continue;
               m[i-1][j2] = pole[index][i][j];
               j2++;
            }
         }
         det += pow(-1.0,1.0+j1+1.0) * pole[index][0][j1] * Determinant(pole,index,rozmer-1);
         for (i=0;i<rozmer-1;i++)
            free(m[i]);
         free(m);
      }
   }
   printf("Determinant %c: %i\n",c,det);
   return (det);
}
akraheb
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 430
Registrovaný: 28 júl 2005, 16:59
Kontaktovať používateľa:

Príspevok od používateľa akraheb »

AK SA DA TAK NAMIESTO CISELNEHO INDEXU OD 0-26 ZADAVAT OD A-Z

to poriesis tak ze zmenis datovy typ z int na char, tym padom sa meni aj pismeno v scanf

char v;
scanf ("%s",&v);
Prílohy
semestralka.docx
moj vytvor
(18.77 KiB) 57 stiahnutí
marcus-16
Star
Star
Používateľov profilový obrázok
Príspevky: 688
Registrovaný: 30 mar 2006, 19:33

Príspevok od používateľa marcus-16 »

problem je v tom, ze si tu pamat pre ***pole alokujes az v tom cykle, takze vzdy ked sa cyklus opakuje, pamat sa `realokuje`(ani neviem ako to funguje, ale urcite to robi v pameti dobru sarapatu :D , cudujem sa ze ten program nepadne)..
..teraz tam ale nastane dalsi problem, kedze si pamat alokujes na zaciatku, pre vsetky matice budes mat nastaveny rovnaky rozmer(co asi nechces), takze takto to nepojde..na tvojom mieste by som asi urobil nejaku strukturu `matica`, a spravil pole struktur..
ja osobne by som to spravil objektovo, pride mi to jednoduchsie, ale to ste asi nebrali..
malinator
Novice
Novice
Používateľov profilový obrázok
Príspevky: 7
Registrovaný: 13 dec 2008, 16:47
Kontaktovať používateľa:

Príspevok od používateľa malinator »

akraheb: dik moc, aj som si myslel ze to jednoducho zmenit na typ ... vyskusam a napisem :D

marcus: no uz som toto rozoberal s jednym kamosom v podstate mi povedal to iste...tak som sa rozhodol ze teda tu alokaciu vyhodim pred ten do while a rozmer bude fixny trebars 4. struct by si dal vytvorit ale to sa mi uz nechce :D a objektove sme nemali este...tak ci tak, diki moc :)

//autoeditácia príspevku ( 30 Dec 2009, 22:30 )
A nemate nejake napady ako vyriesim determinant a inverznu maticu ? :)
picuge
Expert
Expert
Príspevky: 167
Registrovaný: 17 dec 2005, 20:38
Bydlisko: Bratislava/Martin

Príspevok od používateľa picuge »

Ak ti to este treba, tak skus pozriet tu:
http://local.wasp.uwa.edu.au/~pbourke/m ... terminant/
Mas tam kody v c a vsetko pekne vysvetlene ;)
malinator
Novice
Novice
Používateľov profilový obrázok
Príspevky: 7
Registrovaný: 13 dec 2008, 16:47
Kontaktovať používateľa:

Príspevok od používateľa malinator »

to som nasiel aj ja ale implementacia do mojho kodu mi proste nejde :)
picuge
Expert
Expert
Príspevky: 167
Registrovaný: 17 dec 2005, 20:38
Bydlisko: Bratislava/Martin

Príspevok od používateľa picuge »

A naco chces mat index ako vstup funkcie? ...Podla mna takto je to ovela jednoduchsie takto a myslim ,ze by to malo ist:
z (line 11)

Kód: Vybrať všetko

int Determinant(int ***pole, int index, int rozmer); 
na

Kód: Vybrať všetko

int Determinant(int **pole, int rozmer);
z (line 70)

Kód: Vybrať všetko

Determinant(pole,n,rozmer); 
na

Kód: Vybrať všetko

printf("%d" , Determinant(pole[n],rozmer));
a funkcia samotna (funkcia z tej stranky, len som zmenil typ premennych z double na int, kedze si to tak mal aj ty):

Kód: Vybrať všetko

int Determinant(int **a,int n)
{
   int i,j,j1,j2;
   int det = 0;
   int **m = NULL;

   if (n < 1) { /* Error */

   } else if (n == 1) { /* Shouldn't get used */
      det = a[0][0];
   } else if (n == 2) {
      det = a[0][0] * a[1][1] - a[1][0] * a[0][1];
   } else {
      det = 0;
      for (j1=0;j1<n;j1++) {
         m = malloc((n-1)*sizeof(double *));
         for (i=0;i<n-1;i++)
            m[i] = malloc((n-1)*sizeof(double));
         for (i=1;i<n;i++) {
            j2 = 0;
            for (j=0;j<n;j++) {
               if (j == j1)
                  continue;
               m[i-1][j2] = a[i][j];
               j2++;
            }
         }
         det += pow(-1.0,1.0+j1+1.0) * a[0][j1] * Determinant(m,n-1);
         for (i=0;i<n-1;i++)
            free(m[i]);
         free(m);
      }
   }
   return(det);
}
Tym, ze si das index a cele pole matic ako vstup to zbytocne skompikujes.
Napísať odpoveď