Gaussova eliminační metoda – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Gaussova eliminační metoda – C / C++ – Fórum – Programujte.comGaussova eliminační metoda – C / C++ – Fórum – Programujte.com

 

Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
11. 9. 2015   #1
-
0
-

Dobrý den, měla bych na Vás dotaz. Jsem začátečnice v cčku a potřebuji napsat program, který přečte z textového souboru matici soustavy a vektor pravých stran a následně to vyřeší gaussovou metodou. Budu mít zadáno číslo udávající počet rovnic a potom tu matici.

Můj problém je už na začátku, protože nevím jak si uložit do pole ty čísla, v závislosti na počtu rovnic. Protože se mi musí dynamicky alokovat počet vektorů v závislosti na počtu rovnic.

Prosím tedy velmi o radu, protože jsem z toho už zoufalá a lámu si nad tím marně hlavu už přes týden.

Předem mnohokrát děkuji za odpověď.

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
11. 9. 2015   #2
-
0
-

zatím jsem vymyslela toto, ale proostě nemohu na to přijít stále :/ 

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

int main(int argc, char** argv)
{

FILE *vstupni;
  int pocet;
  int *a,*b,*c;
  char jmeno[50];
  int i,n,j,m;



  printf("Zadej jmeno souboru: ");
  gets(jmeno);

  if((vstupni=fopen(jmeno,"rt"))==NULL)
  {
    printf("Vstupni soubor %s nelze otevrit\n",jmeno);
    return -1;
  }
i=0;
for(i=0;i!=1;i++)
{
fscanf(vstupni,"%d",&pocet);

}
printf("%d",pocet);

n=pocet;
m=pocet+1;
int mat[n][m];

for (i=1; i<n; i++)
    for (j=0; j<m; j++)
	{
		fscanf(vstupni,"%d",&mat[i][j]);
	}

 for(i=1;i<n;i++)
  {
    for(j=0;j<m;j++) printf("%d ",mat[i][j]); /* tisk jednoho radku */
    printf("\n"); /* za kazdym radkem odradkuji */
  }

    return (0);
}
Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #3
-
0
-

#2 Pavla Kainráthová
Musíš na to jít jinak... Aktuálně tu matici ani nevytvoříš, protože na stacku způsobem, jak to děláš ty, pole vytvářet nemůžeš, můžeš si takové pole nicméně vytvořit na haldě (pomocí malloc/calloc).

Jakým způsobem to budeš chtít udělat:

1. Soubor by měl být ve formátu, kdy z jednoho řádku můžeš jednoznačně určit, kolik se tam nachází sloupců v matici (neboli proměnných, x,y,z,...). Může vypadat například takhle.

// když se tam proměnná nenachází, použijeme nulu
1;1;2;-3;4;0;0;
 
// když se tam proměnná nenachází, použijeme prázdný index
1;1;2;-3;4;;;
 
V obou případech stejný počet středníků - 7 (7 sloupců/proměnných)

2. Přečteš si, kolik sloupců (budeš počítat třeba ty středníky) tam máš, a ty přiřadíš do proměnné, například N.

3. Přečteš si, kolik řádků v daném souboru máš a ty přiřadíš do proměnné, například M.

4. Na haldě si alokuješ nové dvourozměrné pole reprezentující matici...

int** matice = (int**)malloc(pocetRadku * sizeof(int*));

int i;
for (i = 0; i < pocetRadku; ++i) {
    matice[i] = (int*)malloc(pocetSloupcu * sizeof(int));
}

A teď musíš ten soubor přečíst znova, když už víš, že máš matici, která odpovídá rozměrům, a teprve do ní nacpat hodnoty.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #4
-
0
-

ahoj, mockrát děkuji :)) mám to přesně jak jste napsal, spočítala jsem počet řádků i sloupců, ale těd ohledně toho skenování pole když to udělám jako to mám výše, tak mi to vypíše naprosto bláznivé hodnoty. 

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

int main(int argc, char** argv)
{

FILE *vstupni;
  int pocetRadku;
  int *a,*b,*c;
  char jmeno[50];
  int i,n,j,m;
  char strednik;
  int znak,pocetSloupcu;
  znak=0;



  printf("Zadej jmeno souboru: ");
  gets(jmeno);

  if((vstupni=fopen(jmeno,"rt"))==NULL)
  {
    printf("Vstupni soubor %s nelze otevrit\n",jmeno);
    return -1;
  }
i=0;
for(i=0;i!=1;i++)
{
fscanf(vstupni,"%d",&pocetRadku);

}
while ((strednik=fgetc(vstupni))!=EOF)
  {
     if(strednik==';') znak++;

     }
     pocetSloupcu=znak/pocetRadku;
     printf("%d\n",pocetSloupcu);


int** matice = (int**)malloc(pocetRadku * sizeof(int*));


for (i = 0; i < pocetRadku; ++i) {
    matice[i] = (int*)malloc(pocetSloupcu * sizeof(int));
}

for (i=1; i<pocetSloupcu; i++)
                {for (j=0; j<pocetRadku; j++)

                        fscanf(vstupni,"%d",&matice[i]);
                }

  for(i=1;i<pocetSloupcu;i++)
  {
    for(j=0;j<pocetRadku;j++)
        printf("%d ",matice[i]);
    printf("\n");
  }


    return (0);
}
Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #5
-
0
-

#4 Pavla Kainráthová
Můžeš se inspirovat tady, toto ti řádky a sloupce počítá správně...

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

typedef struct MatrixInfo
{
	int columnCount;
	int rowCount;
} MatrixInfo;

int countColumns(FILE* inputFile, const char delimiter)
{
	char buffer[255];
	
	fgets(buffer, 255, inputFile);

	int columnCount = 0;
	int i = 0;

	while (buffer[i] != '\n')
	{
		if (buffer[i] == delimiter) {
			++columnCount;
		}

		++i;
	}

	rewind(inputFile);

	return columnCount;
}

int countRows(FILE* inputFile)
{
	int buffer;
	
	int rowCount = 1;

	do
	{
		buffer = fgetc(inputFile);

		if (buffer == '\n') {
			++rowCount;
		}
	} while (buffer != EOF);

	rewind(inputFile);

	return rowCount;
}

MatrixInfo countRowsAndColumnsInFile(FILE* inputFile)
{
	MatrixInfo matrixInfo;

	matrixInfo.columnCount = 0;
	matrixInfo.rowCount = 0;

	if (inputFile == NULL) {
		return matrixInfo;
	}

	matrixInfo.columnCount = countColumns(inputFile, ';');

	if (matrixInfo.columnCount > 0) {
		matrixInfo.rowCount = countRows(inputFile);
	}

	return matrixInfo;
}

int main(int argc, char **argv)
{
	FILE* matrixFile = fopen("matice.txt", "rt");
	
	MatrixInfo matrixInfo = countRowsAndColumnsInFile(matrixFile);

	fclose(matrixFile);
	
	return 0;
}
Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #6
-
0
-

mockrát děkuji za odpověď. Já počet řádků i sloupců určit dokáži. Ale mám problém s tím načítáním do matice. Tam je ten háček :))

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #7
-
0
-

#6 Pavla Kainráthová
Když už máš matici hotovou se správnými rozměry, načti ten soubor znovu.Všimni si, že se ti hodnoty načítají do pole charů, ty si to pole musíš ještě převést na integery (například pomocí atoi). A teprve jak budeš mít znaky převedené na celá čísla, tak je můžeš přiřadit do té matice celých čísel.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #8
-
0
-

Super mockrát děkuji, těd už ty výsledky odpovídají. Akorát bych měla asi hloupý dotaz, a omlouvám se, že tě pořád otravuji, ale nevím jak ři načítání té matice přeskočit to první číslo tj. počet rovnic. Protože at si hraju s ičkem jak chci pořád to nehází správná čísla.

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #9
-
0
-

#8 Pavla Kainráthová
Jaké číslo máš na mysli?

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #10
-
0
-

Ona matice je v tomto tvaru. Ta 2 udává počet rovnic. A já když dám načtení a vypsání pole, tak mi to vypíše matici od 2 do 7.

2
10 30 
6 5 7

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #11
-
0
-

pardon od 2 do 5

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #12
-
0
-

#10 Pavla Kainráthová
Jestli formát souboru bude vždy ten, že první číslo je počet rovnic, tak prostě první číslo ignoruj a máš to, ne?

Odlaď si ten program, podívej se, co se nachází v proměnných, z nichž taháš například ta čísla 2-5 a na základě jejich obsahu si uprav kód.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
12. 9. 2015   #13
-
0
-

to jsem právě zkusila a udělala to takto, ale program vždy přestane pracovat

for (i=1; i<(pocetRadku+1); i++)
                {for (j=0; j<pocetSloupcu; j++)
                
                 fscanf(vstupni,"%d",&matice[i][j]);
                }

  for(i=0;i<pocetRadku;i++)
  {
    for(j=0;j<pocetSloupcu;j++)
        printf("%d ",matice[i][j]);
    printf("\n");
  }
Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:896:70...–
ondrej39+1
Věrný člen
12. 9. 2015   #14
-
0
-

#13 Pavla Kainráthová
Problém není v int i, ale ve funkci fscanf. Schválně pusť funkci fscanf jednou před tím prvním for cyklem, její výsledek si přiřaď třeba do proměnné int dump, ve for cyklu indexuj i od nuly a podívej se, co ti to udělalo.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Pavla Kainráthová
~ Anonymní uživatel
9 příspěvků
13. 9. 2015   #15
-
0
-

Mockrát ti děkuji, díky tvé pomoci už to načítání funguje bez problému. Těd se však snažím přidat onu gaussovu eliminační metodu. A jsem zase ztracená :( 

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

int main(int argc, char** argv)
{

FILE *vstupni;
char jmeno[255];
int c,r,k;
int i=0,j=0,pocetRadku=0,pocetrovnic=0;
int *pocetSloupcu;
float **matice, x[10], sum;



  printf("Zadej jmeno souboru: ");
  gets(jmeno);

  if((vstupni=fopen(jmeno,"rt"))==NULL)
  {
    printf("Vstupni soubor %s nelze otevrit\n",jmeno);
    return -1;
  }


    while((c = getc(vstupni)) != EOF){
        if(c == '\n')
        pocetRadku++;
    }

    printf("\npocet radku %d",pocetRadku);
    printf("\n");

    pocetrovnic=pocetRadku-1;
    printf("pocet rovnic je %d\n\n",pocetrovnic);



       //jednorozmerne pole pro urceni poctu sloupcu
    pocetSloupcu= (int*) calloc( pocetRadku , sizeof(int)); //pocet sloupcu nacitame pres pole

    rewind(vstupni);
    while((c = getc(vstupni)) != EOF)
        { /* přečtení souboru */
        while((c =getc(vstupni)) != '\n')
        {
            if(c == ' ' )
            { //postupne scitame pocty mezer
            pocetSloupcu[i]++;
            }
        }
        pocetSloupcu[i]++; // pridavam jednicku kvuli tomu, ze v poslednim sloupci matice neni mezera
        i++;
        }
    matice = (int **)calloc( pocetRadku , sizeof(int *)); //zde si alokuju kolik ma mit matice radku
    rewind(vstupni);

//načítání matice
    for(i= 0; i< pocetRadku ; i++){
        matice[i] = (int *)calloc( pocetSloupcu[i] , sizeof(int));  //tady alokuju sloupecky kazdeho radku
        for(j=0; j<pocetSloupcu[i]; j++){
            fscanf(vstupni, "%f", &matice[i][j]);   //tady matici plním
        }
    }
// vypisování matice, když změním i=0 na i=1 tak budu mít matici bez prvního čísla (urcovacího pocet rovnic)
    for(i = 0; i < pocetRadku ; i++){
        for (j = 0; j < pocetSloupcu[i]; j++)
            printf("%f ", matice[i][j]);
        printf("\n");
    }



//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
//GAUSSOVKA---------------------------------------------

for(j=0; j<=pocetrovnic; j++)
    {
        for(i=0; i<=pocetrovnic; i++)
        {
            if(i>j)
            {
                r=matice[i][j]/matice[j][j];
                for(k=0; k<=pocetrovnic+1; k++)
                {
                    matice[i][k]=matice[i][k]-r*matice[j][k];
                }
            }
        }
    }

x[pocetrovnic]=matice[pocetrovnic][pocetrovnic+1]/matice[pocetrovnic][pocetrovnic];

    for(i=pocetrovnic-1; i>=1; i--)
    {
        sum=0;
        for(j=i+1; j<=pocetrovnic; j++)
        {
            sum=sum+matice[i][j]*x[j];
        }
        x[i]=(matice[i][pocetrovnic+1]-sum)/matice[i][i];
    }

printf("\nvýsledek je: \n:");

    for(i=0; i<=pocetrovnic; i++)
    {
        printf("\nx%d=%f\t",i,x[i]);
    }





  system("PAUSE");
  return 0;
}
Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:81c8:6...–
Pavla Kainrátová
~ Anonymní uživatel
1 příspěvek
15. 9. 2015   #16
-
0
-

Nevíte prosím, kde přesně dělám tu chybu? Stále jsem na to nepřišla...

Nahlásit jako SPAM
IP: 2a00:1028:919e:39a:b98b:1...–
peter
~ Anonymní uživatel
3981 příspěvků
15. 9. 2015   #17
-
0
-

Predpokladej ale, ze o tom vubec nic nevim. Ja bych treba nasel kod googlem a upravil.
Taky by mozna bylo dobre pridat vstupni data, co presne vypise ten cyklus for(i = 0; i < pocetRadku ; i++){ for (j = 0; j < pocetSloupcu[i]; j++).

matici vypisujes pres
for(i = 0; i < pocetRadku ; i++){ for (j = 0; j < pocetSloupcu[i]; j++)

ale s matici pracujes jako
for(j=0; j<=pocetrovnic; j++) { for(i=0; i<=pocetrovnic; i++) { if(i>j) {

Je pocetRadku == pocetSloupcu[i] == pocetrovnic - 1 ?
Proc pri vypisu mas i,j cyklus a pro praci j,i?
Proc je tam k<=pocetrovnic+1?
Proc je tam matice[i][j]/matice[j][j] --- matice[j][j]?
Proc je tam x[pocetrovnic]=matice[pocetrovnic][pocetrovnic+1] --- pocetrovnic+1?
Mimochodem, rychlejsi je --j a ++i zapis, ale to je detail.
(To je jako seznam podezrelych mist na prvni pohled. Mozna je to vsechno spravne.)

 

Nahlásit jako SPAM
IP: 193.84.207.–
peter
~ Anonymní uživatel
3981 příspěvků
15. 9. 2015   #18
-
0
-

Traba, tady ten manik to ma pres funkce a zadava tam vlastni matici
http://www.schovan.net/…matice.c.txt
matrix[0] = 1;
matrix[1] = 2;
Predpoklada, ze pocet radku a sloupcu je stejny. Oznacil to jako size, kratke jednoduche slovo. Kdyz pouzijes pocetSloupcu, pocetRadku, opticky to pusobi jako jedno slovo pocetXXX a musi se to peclive cist.
 

Nahlásit jako SPAM
IP: 193.84.207.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 42 hostů

Podobná vlákna

Gaussova eliminační metoda — založil Blujacker

Gaussova eliminační metoda — založil Novice

Gaussova kvadratura — založil AshiaToka

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý