Witam,
mam za zadanie napisac program wykonujacy podstawowe operacje na macierzach (dodawanie, odejmowanie, odwracanie, mnozenie, transponowanie). Ponizej umieszczam to co napisalam. Prosilabym o konstruktywna krytyke (co i dlaczego oraz jak lepiej), bo sa to moje poczatki z programowaniem wiec sporo pewnie jest do naprawy.
aha - na poczatku myslalam o stworzeniu tablic 2wymiarowej - ale mialam problemy z jej dynamicznym przydzialem pamieci i operacjach na takowej tablicy, wiec obeszlam to tworzac tablice 1wymiarowe.
najwieksze watpliwosci mam co do funkcji zaokraglij - to zaokraglanie jakos tak tez na okrak jest zrobione - ale niestety nie udalo mi sie znaleŹĆ funkcji wbudowanej np. takiej: nazwa(miejsc_po_przec, liczba) ktora by zaokraglala do zadanej ilosci miejsc po przecinku - ale zapewne cos takiego istnieje - tylko mi sie nie udalo znaleŹĆ [wstyd]
Sprawa druga ze jezeli uzytkownik poda jako zaokraglenie litere to program sie wywala... grr.. myslalam o tym ze user podawal by zmienna typu char i zamienialabym to na liczbe typu int. Czy da sie to jakos logicznie zorganizowac?
O ile
char lit;
int licz;
lit='8';
licz=(int(lit)-48);
da poprawny wynik to juz przy liczbach wiekszych od 9 nie zamienia poprawnie. Z atoi ten sam problem.
Caly kod
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
void wykonaj(char ch, int nr, ofstream *f);
/* ******************************************************************************************************************** */
/* PROGRAM GLOWNY - PROGRAM GLOWNY - PROGRAM GLOWNY - PROGRAM GLOWNY - PROGRAM GLOWNY - PROGRAM GLOWNY - PROGRAM GLOWNY */
/* ******************************************************************************************************************** */
int main()
{
char ch,str[10];
int nr;
ofstream fout("out.txt");
for(nr=1;;nr++) {
do {
cout<<" MENU\n\n";
cout<<" D .. Dodawanie\n";
cout<<" O .. Odejmowanie\n";
cout<<" T .. Transponowanie\n";
cout<<" M .. Mnozene\n";
cout<<" S .. Szukanie macierzy odwrotnej\n";
cout<<" K .. Koniec\n";
cout<<"\t Twoj wybor: ";
cin>>str;
ch = toupper(*str);
if (ch!='D' && ch!='K' && ch!='O' && ch!='M' && ch!='T' && ch!='S') cout<<"\n (!!!) Nie ma takiej mozliwosci!\n\n";
} while(ch!='D' && ch!='K' && ch!='O' && ch!='M' && ch!='T' && ch!='S');
if (ch=='K') { fout.close(); exit(0); }
else wykonaj(ch,nr,&fout);
cout<<"\n================================================\n\n";
}
return 0;
}
/* ********************************************************************************************************************* */
/* DEFINICJE FUNKCJI - DEFINICJE FUNKCJI - DEFINICJE FUNKCJI - DEFINICJE FUNKCJI - DEFINICJE FUNKCJI - DEFINICJE FUNKCJI */
/* ********************************************************************************************************************* */
/* ENTER MACIERZ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
void enter_wym(int *w, int *k, int nr) /* podawanie wymiaru */
{
cout<<"\nPodaj wymiar macierzy "<<nr<<"\n";
do{ cout<<"\t-- Wierszy "; cin>>*w; if (*w==0) cout<<"\n (!!!) Nie mozesz podac zerowego wymiaru!\n\n"; }while(*w==0);
do{ cout<<"\t|| Kolumn "; cin>>*k; if (*k==0) cout<<"\n (!!!) Nie mozesz podac zerowego wymiaru!\n\n"; }while(*k==0);
}
void enter_el(int w, int k, double *tab, int nr) /* wprowadzanie elem macierzy */
{
cout<<"\nPodaj elementy macierzy "<<nr<<"\n";
for (int i=0,j=1,g=1;i<w*k;i++)
{
cout<<"\tPodaj elemnt ("<<j<<"/"<<g<<") ";
cin>>tab[i];
if (g==k) { g=0; j++; }
g++;
}
}
/* WYSWIETLANIE WYNIKU ##################################################################################### */
void wyswietl(int w, int k, double *tab_wynik) /* wyswietlanie wyniku na ekranie */
{
cout<<"\n-------------\n| Wynik to: |\n-------------\n\n";
for (int i=0,j=1;i<w*k;i++)
{
cout<<" "<<tab_wynik[i];
if(i+1==j*k) {cout<<"\n"; j++;}
}
cout<<"\n";
}
void zaokraglenie(int w, int k, double *tab_wynik) /* zakraglanie wynikow */
{
int zaokr,i,j,licz;
double *tab_temp;
tab_temp = new double [w*k];
zaokr=-3;
for(i=0;i<w*k;i++) tab_temp[i]=tab_wynik[i];
//tabela temp pamieta wyniki bez zaokraglenia, tab3 pamieta wynik z aktualnie wprowadzinym zaokragleniem
do {
if (zaokr==-3) cout<<"\nWynik bez zaokraglenia:\n\n";
else cout<<"\nCzy ponizsze zaokraglenie Ci odpowiada?\n\n";
for(i=0,j=1;i<w*k;i++) {
if (zaokr>=0) tab_wynik[i]=(ceil(tab_temp[i]*licz))/licz;
cout<<" "<<tab_wynik[i];
if(i+1==j*k) {cout<<"\n"; j++;}
}
cout<<"\n\tPodaj zaokraglenie {miejsc po przecinku}\n\t-1 jezeli bez zaokraglenia\n\t-2 jezeli zaokraglenie Ci odpowiada\n";
do {
cout<<"\t\tTwoj wybor: ";
cin>>zaokr;
if (zaokr!=-1 && zaokr!=-2 && zaokr<0 ) cout<<"\t\t\tPodaj -1, -2 lub liczbe >=0\n";
}while (zaokr!=-1 && zaokr!=-2 && zaokr<0);
if (zaokr>=0) for(i=1,licz=1;i<=zaokr;i++) licz=licz*10;
}while (zaokr!=-2);
}
/* OPERACJE ================================================================================================ */
void dodaj(int w, int k, double *tab1, double *tab2, double *tab_wynik) /* dodawanie */
{
for (int i=0;i<w*k;i++) tab_wynik[i]=tab1[i]+tab2[i];
}
void odej(int w, int k, double *tab1, double *tab2, double *tab_wynik) /* odejmowanie */
{
for (int i=0;i<w*k;i++) tab_wynik[i]=tab1[i]-tab2[i];
}
void tran(int w, int k, double *tab1, double *tab_wynik) /* transponowanie */
{
for (int j=0,i=0,g=1;j<w*k;j++)
{
tab_wynik[j]=tab1[i];
i=i+k;
if (j+1==g*w) { g++; i=g-1; }
}
}
void mnoz(int k1w2, int k2, int w1, double *tab1, double *tab2, double *tab_wynik) /* mnozenie */
{
for (int g=0;g<k2;g++)
for (int i=0,f=g;i<w1*k1w2;f+=k2)
{
tab_wynik[f]=0;
for (int j=g,k=0;k<k1w2;j+=k2,i++,k++) tab_wynik[f]=tab_wynik[f]+tab1[i]*tab2[j];
}
}
double wyznacz(int w, double *tab1) /* sprawdzenie czy mozna policzyc mac odwrotna */
{
int i,j,g,f,wiel1,wiel2,licznik1,licznik2;
double suma1,suma2,dz1,dz2;
if (w==1) return tab1[0];
else
{
i=g=0;
do {
suma1=suma2=wiel1=wiel2=licznik1=licznik2=0;
j=g;f=0;
dz1=tab1[i]/tab1[i+w];
dz2=tab1[j]/tab1[j+1];
do {
suma1=suma1+tab1[i]; //zerowy wiersz
suma2=suma2+tab1[j]; //zerowa kolumna
if (i+w<w*w) {
if (dz1==tab1[i]/tab1[i+w]) wiel1++; //proporcjonalnosc wierszy
if (dz2==tab1[j]/tab1[j+1]) wiel2++; //proporcjonalnosc kolumn
if (tab1[i]==tab1[i+w]) licznik1++; //rownosc wierszy
if (tab1[j]==tab1[j+1]) licznik2++; //rownosc kolumn
};
j+=w;f++;i++;
} while (f<w);
g++;
} while (i<w*w && licznik1<w && licznik2<w && suma1!=0 && suma2!=0 && wiel1<w && wiel2<w);
if (licznik1>=w || licznik2>=w || suma1==0 || suma2==0 || wiel1>=w || wiel2>=w) return 0;
else return 1;
}
}
void odwr(int W, double *tab1, double *tab_wynik) /* odwracanie */
{
int i,ii,j,jj,k,kk,gg;
for(i=0;i<W*W;i++) tab_wynik[i]=tab1[i];
// >>>> BEGIN: Zmodyfikowany kod ze strony http://www.ee.pw.edu.pl/~tomzdun/index.php?mid=2253
for(i=0,ii=0;i<W;i++,ii+=W+1)
{
tab_wynik[ii] = 1./tab_wynik[ii];
for(j=0,jj=i;j<W;j++,jj+=W)
if(j!=i)
{
tab_wynik[jj] = tab_wynik[jj]*tab_wynik[ii];
for (k=0,kk=jj-i,gg=ii-i;k<W;k++,kk++,gg++) {
if(k!=i)
{
tab_wynik[kk] -= tab_wynik[jj]*tab_wynik[gg];
if(j==(W-1))
tab_wynik[gg] = -(tab_wynik[gg]*tab_wynik[ii]);
}
}
}
}
if (W>1)
for(;kk<gg-1;kk++) {
tab_wynik[kk] = -(tab_wynik[kk]*tab_wynik[gg-1]);
}
// >>>> END
}
/* ZAPISANIE DO PLIKU @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
void zap(int w, int k, double *tab_elem, ofstream *f) /* w pliku wynikowym wypisanie macierzy operacyjnych */
{
for (int i=0,j=1;i<w*k;i++)
{
(*f)<<tab_elem[i];
if(i+1==j*k && i+1!=w*k) {(*f)<<" / "; j++;}
else if (i+1!=w*k) (*f)<<", ";
}
}
void zapisz(int w, int k, int k2, char ch, int nr, ofstream *f, double *tab1, double *tab2, double *tab_wynik) /* zapisanie do pliku wynikow */
{
int i,j;
char tn,ciag[10];
cout<<"\tZapisac wyniki do pliku? (out.txt)\n";
do {
cout<<"\t\t(T)ak\n";
cout<<"\t\t(N)ie\n";
cout<<"\t\t\tTwoj wybor: ";
cin>>ciag;
tn = toupper(*ciag);
if (tn!='T' && tn!='N') cout<<"\nNie ma takiej mozliwosci!\n\n";
} while(tn!='T' && tn!='N');
if (tn=='T') {
(*f)<<"Wynik operacji nr "<<nr;
switch (ch) {
case 'M' :
(*f)<<", mnozenie,\n\tmacierzy ("<<w<<", "<<k<<") = {"; /*oo*/ zap(w,k,&*tab1,&*f); /*oo*/ (*f)<<"}, z\n\tmacierza ("<<k<<", "<<k2<<") = {"; /*oo*/ zap(k,k2,&*tab2,&*f); /*oo*/ (*f)<<"}, to:\n\n";
k=k2;break;
case 'T' :
(*f)<<", transponowanie,\n\tmacierzy ("<<w<<", "<<k<<") = {"; /*oo*/ zap(w,k,&*tab1,&*f); /*oo*/ (*f)<<"}, to:\n\n";
i=w; w=k; k=i; break;
case 'S' :
(*f)<<", odwracanie,\n\tmacierzy ("<<w<<", "<<w<<") = {"; /*oo*/ zap(w,w,&*tab1,&*f); /*oo*/ (*f)<<"}, to:\n\n";
break;
case 'D' :
(*f)<<", dodawanie,\n\tmacierzy ("<<w<<", "<<k<<") = {"; /*oo*/ zap(w,k,&*tab1,&*f); /*oo*/ (*f)<<"}, do\n\tmacierzy ("<<w<<", "<<k2<<") = {"; /*oo*/ zap(w,k2,&*tab2,&*f); /*oo*/ (*f)<<"}, to:\n\n";
break;
case 'O' :
(*f)<<", odejmowanie,\n\tod macierzy ("<<w<<", "<<k<<") = {"; /*oo*/ zap(w,k,&*tab1,&*f); /*oo*/ (*f)<<"},\n\tmacierzy ("<<w<<", "<<k2<<") = {";zap(w,k2,&*tab2,&*f); /*oo*/ (*f)<<"}, to:\n\n";
break;
}
if (k2==-1) (*f)<<" Tej macierzy nie mozna odwrocic\n";
else
for (i=0,j=1;i<w*k;i++)
{
(*f)<<" "<<tab_wynik[i];
if(i+1==j*k) {(*f)<<"\n"; j++;}
}
(*f)<<"\n\n";
}
}
/* GLOWNE WYWOLANIE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
void wykonaj(char ch, int nr, ofstream *f) /* funkcja glowna */
{
int w1,k1,w2,k2;
double *tab1,*tab2,*tab3;
switch (ch)
{
/* wybrano dodawanie */
case 'D' :
do {
enter_wym(&w1,&k1,1);
enter_wym(&w2,&k2,2);
if (k1!=k2 || w1!=w2) cout<<"\n (!!!) Macierzy o takich wymiarach nie da sie dodac. Wymiary musza byc rowne.\n";
}while(k1!=k2 || w1!=w2);
tab1 = new double [w1*k1];
tab2 = new double [w1*k1];
tab3 = new double [w1*k1];
enter_el(w1,k1,&*tab1,1);
enter_el(w1,k1,&*tab2,2);
dodaj(w1,k1,&*tab1,&*tab2,&*tab3);
zaokraglenie(w1,k1,&*tab3);
wyswietl(w1,k1,&*tab3);
zapisz(w1,k1,k1,ch,nr,&*f,&*tab1,&*tab2,&*tab3);
free(tab1);free(tab2);free(tab3);
break;
/* wybrano odejmowanie */
case 'O' :
do {
enter_wym(&w1,&k1,1);
enter_wym(&w2,&k2,2);
if (k1!=k2 || w1!=w2) cout<<"\n (!!!) Macierzy o takich wymiarach nie da sie odjac. Wymiary musza byc rowne.\n";
}while(k1!=k2 || w1!=w2);
tab1 = new double [w1*k1];
tab2 = new double [w1*k1];
tab3 = new double [w1*k1];
enter_el(w1,k1,&*tab1,1);
enter_el(w1,k1,&*tab2,2);
odej(w1,k1,&*tab1,&*tab2,&*tab3);
zaokraglenie(w1,k1,&*tab3);
wyswietl(w1,k1,&*tab3);
zapisz(w1,k1,k2,ch,nr,&*f,&*tab1,&*tab2,&*tab3);
free(tab1);free(tab2);free(tab3);
break;
/* wybrano transponowanie */
case 'T' :
enter_wym(&w1,&k1,1);
tab1 = new double [w1*k1];
tab2 = new double [w1*k1];
enter_el(w1,k1,&*tab1,1);
tran(w1,k1,&*tab1,&*tab2);
zaokraglenie(k1,w1,&*tab2);
wyswietl(k1,w1,&*tab2);
zapisz(w1,k1,0,ch,nr,&*f,&*tab1,0,&*tab2);
free(tab1);free(tab2);
break;
/* wybrano mnozenie */
case 'M' :
do {
enter_wym(&w1,&k1,1);
enter_wym(&w2,&k2,2);
if (k1!=w2) cout<<"\n (!!!) BLAD! Zly wymiar. Prawidlowy wymiar to w m1 = k m2\n";
}while(k1!=w2);
tab1 = new double [w1*k1];
tab2 = new double [w2*k2];
tab3 = new double [w1*k2];
nr=1;
enter_el(w1,k1,&*tab1,1);
enter_el(w2,k2,&*tab2,2);
mnoz(k1,k2,w1,&*tab1,&*tab2,&*tab3);
zaokraglenie(w1,k2,&*tab3);
wyswietl(w1,k2,&*tab3);
zapisz(w1,k1,k2,ch,nr,&*f,&*tab1,&*tab2,&*tab3);
free(tab1);free(tab2);free(tab3);
break;
/* wybrano odwracanie */
case 'S' :
do {
enter_wym(&w1,&k1,1);
if (w1!=k1) cout<<"\n (!!!) Odwracac mozna tylko macierz kwadratowa\n";
}while(w1!=k1);
tab1 = new double [w1*k1];
tab2 = new double [w1*k1];
enter_el(w1,k1,&*tab1,1);
if(wyznacz(w1,&*tab1)!=0) {
odwr(w1,&*tab1,&*tab2);
zaokraglenie(w1,w1,&*tab2);
wyswietl(w1,w1,&*tab2);
zapisz(w1,k1,0,ch,nr,&*f,&*tab1,0,&*tab2);
}
else {
cout<<"\n-------------\n| Wynik to: |\n-------------\n\n Tej macierzy nie da sie odwrocic\n\n";
zapisz(w1,k1,-1,ch,nr,&*f,&*tab1,0,&*tab2);
}
free(tab1);free(tab2);
break;
}
}