Tohle je ta asi 5x rychlejsi varianta od te puvodni. Osetreny varovne hlasky, pridana knihovna pro malloc a zruseno getch(). Odstranena maticeD a do poleB se rovnou nacita po sloupcich a ne po radcich. Obe matice musi byt ctvercove o shodne velikosti.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define VELIKOST 1000
// #define NACITANI
// #define VYPIS_MATIC
int main(){
clock_t startCteni1,konecCteni1,startCteni2,konecCteni2,startNasob,konecNasob,startZapis,konecZapis;
#ifdef NACITANI
printf("Program na vypocet nasobeni matic - neresime jako matici nybrz jako pole\n");
char nazevSouboru1 [15];
printf("Vlozte jmeno souboru pro matici 1 :");
if ( scanf("%15s",nazevSouboru1) <= 0 ) // pozor cteme pouze prvnich 15 znaku --- %15s
{
fprintf(stderr, "Spatny nazev souboru?\n" );
return -1;
}
char nazevSouboru2 [15];
printf("Vlozte jmeno souboru pro matici 2 :");
if ( scanf("%15s",nazevSouboru2) <= 0 ) // pozor cteme pouze prvnich 15 znaku --- %15s
{
fprintf(stderr, "Spatny nazev souboru?\n" );
return -1;
}
FILE *fr1,*fr2;
fr1 = fopen(nazevSouboru1,"r"); // nacteme soubor 1
#endif
int velikost1,velikost2;
#ifdef NACITANI
if ( fscanf(fr1,"%i",&velikost1) != 1 ) // nacteme velikost matice
{
fprintf(stderr, "Reading error.\n" );
return -1;
}
#else
velikost1 = VELIKOST;
#endif
printf("Zde je prvni cislo prvni matice : %i\n",velikost1);
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) POLE1 **/
int i,j,k;
int *poleA;
if ( ( poleA = (int *) malloc(velikost1*velikost1*sizeof(int))) == NULL ) {
fprintf(stderr, "No free memory.\n" );
return -1;
}
/*** Naplnime pole z nacteneho souboru ***/
printf("Nacitame matici 1 a prevedeme do pole \n");
startCteni1=clock();
for(i=0;i<(velikost1*velikost1);i++) {
#ifdef NACITANI
if ( fscanf(fr1,"%i",&poleA[i]) != 1 ) {
fprintf(stderr, "Nelze nacist cislo matice A.\n" );
return -1;
}
#else
poleA[i] = rand() & 0xffff;
#endif
}
konecCteni1=clock();
printf("Nacitani prvni matice trvalo %6.2f sec\n",(konecCteni1-startCteni1)/(double) CLOCKS_PER_SEC);
#ifdef VYPIS_MATIC
printf("Zde je nactene PoleA\n");
k = 0;
for(i=0;i<velikost1;i++) {
for(j=0;j<velikost1;j++) printf("%i \t",poleA[k++]);
printf("\n");
}
#endif
#ifdef NACITANI
fclose(fr1);
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) POLE2 **/
fr2 = fopen(nazevSouboru2,"r"); // nacteme soubor 2
if ( fscanf(fr2,"%i",&velikost2) != 1 ) {
fprintf(stderr, "Reading error.\n" );
return -1;
}
#else
velikost2 = VELIKOST;
#endif
printf("Zde je prvni cislo druhe matice: %i\n",velikost2);
int *poleB;
if ( (poleB=(int*)malloc(velikost2*velikost2*sizeof(int))) == NULL ) {
fprintf(stderr, "No free memory.\n" );
return -1;
}
/*** Naplnime pole z nacteneho souboru ***/
printf("Nacitame matici 2 a prevedeme do pole \n");
startCteni2=clock();
for(i=0;i<velikost2;i++) {
for(j=0,k=i;j<velikost2;j++,k+=velikost2) {
#ifdef NACITANI
if ( fscanf(fr2,"%i",&poleB[k]) != 1 ) {
fprintf(stderr, "Nelze nacist cislo matice B.\n" );
return -1;
}
#else
poleB[k] = rand() & 0xffff;
#endif
}
}
konecCteni2=clock();
printf("Nacitani druhe matice trvalo %6.2f sec\n",(konecCteni2-startCteni2)/(double) CLOCKS_PER_SEC);
#ifdef VYPIS_MATIC
printf("Zde je nactene PoleB\n");
k = 0;
for(i=0;i<velikost2;i++) {
for(j=0;j<velikost2;j++) printf("%i \t",poleB[k++]);
printf("\n");
}
#endif
#ifdef NACITANI
fclose(fr2);
#endif
/** Nutne je prevest matici na pole **/
/** DEKLARUJEME A INICIALIZUJEM(ALOKUJEME) MATICI C pointeru na pointer **/
printf("Provadime nasobeni matic \n");
int *poleC;
if ( (poleC=(int*)malloc(velikost1*velikost2*sizeof(int))) == NULL ) {
fprintf(stderr, "No free memory.\n" );
return -1;
}
/************* Nasobime matici A x B = vznik matice C *******************/
startNasob=clock();
int A_old = 0;
int B_new = 0;
int A_new;
int C_new = 0;
int radek = velikost1;
while ( radek-- ) {
B_new = 0;
int sloupec = velikost1;
while ( sloupec-- ) {
A_new = A_old;
int hodnota = 0;
int i = velikost1;
while ( i-- ) hodnota += poleA[A_new++] * poleB[B_new++];
poleC[C_new++] = hodnota;
}
A_old = A_new;
}
konecNasob = clock();
printf("Doba nasobeni matice %6.2f sec\n",(konecNasob-startNasob)/(double) CLOCKS_PER_SEC);
#ifdef VYPIS_MATIC
printf("Zde je vypoctený vynasobeny vektor\n");
k = 0;
for(i=0;i<velikost2;i++) {
for(j=0;j<velikost2;j++) printf("%i \t",poleC[k++]);
printf("\n");
}
#endif
/****************** Ulozime matici do Souboru ***************************/
free(poleA);poleA=NULL; // vymazeme hodnoty a referenci
free(poleB);poleB=NULL; // vymazeme hodnoty a referenci
char nazevSouboru3 [15];
printf("Vlozte jmeno souboru pro matici 3 (vyslednou):");
if ( scanf("%15s",nazevSouboru3) <= 0 ) // pozor cteme pouze prvnich 15 znaku --- %15s
{
fprintf(stderr, "Spatny nazev souboru?\n" );
return -1;
}
FILE *fr3;
fr3 = fopen(nazevSouboru3,"w"); // nacteme soubor 1
fprintf(fr3,"%i\n",velikost1); // ulozime rad matice
startZapis =clock();
k = 0;
for(i=0;i<velikost2;i++) {
for(j=0;j<velikost2;j++) {
fprintf(fr3,"%i ",poleC[k++]);
}
fprintf(fr3,"\n");
}
konecZapis = clock();
printf("Doba ukladani matice %6.2f sec\n",(konecZapis-startZapis)/(double) CLOCKS_PER_SEC);
fclose(fr3);
free(poleC);poleC=NULL; // vymazeme hodnoty a referenci
printf("Program ukoncite stiknutim libovolne klavesy\n");
// getch(); // cekame na stiknuti klavesnice
}