transponowanie macierzy c++

0

witam mam takie zadanie: Utwórz klasę z macierzą double o wymiarach 3*3. Klasa powinna zawierac : funkcję Wczytaj_macierz, Transponuj_macierz, Wypisz_macierz.
Nie bardzo znam się na klasach i zrobiłam taki program ale mi się on nie kompiluje bo w ostatniej linijce jest błąd proszę o pomoc, czemu wywala mi błąd i proszę o sprawdzenie kodu czy jest dobrze napisany.


#include<iostream>

using namespace std;
 
class macierz
{
 void wczytaj_macierz(int n , int m)
{
 
  cout << "Liczba wierszy: ";
   cin >> n;
   cout << "Liczba kolumn: ";
   cin >> m;
   double macierz[n][m];
   double macierzT[m][n];
   
   for(int i = 0; i < n; i++) //wstawianie danych
   {
       for(int j = 0;j < m; j++)
       {
         cout << "Wyraz [" << i << "][" << j << "]: "; 
         cin >> macierz[i][j];   cin.get();
       }   
   }  cin.get();
}
void transponuj_macierz(int n, int m)
{   
   for(int i = 0; i < n; i++) //transponowanie macierzy
   {
       for(int j = 0;j < m; j++)
         macierzT[j][i]=macierz[i][j];
   }
}
void wypisz_macierz(int n , int m)
{  
   cout << "Macierz:" << endl;
   for(int i = 0; i < n; i++) //wyswietlanie macierzy
   {
       for(int j = 0;j < m; j++)
       {
         cout << macierz[i][j] << " ";
       }
       cout << endl;
   }
   
   cout << endl;

{  
   cout << "Macierz transponowana:" << endl;
   for(int i = 0; i < m; i++) //wyswietlanie macierzy transponowanej
   {
       for(int j = 0;j < n; j++)
       {
         cout << macierzT[i][j] << " ";
       }
       cout << endl;
   }
} // koniec funkcji wypisz_macierz  //

int main()
{
void macierz:: wczytaj_macierz(int n , int m)

void macierz transponuj_macierz(int n , int m)  

void macierz wypisz_macierz(int n , int m)
cin.get();
   return 0;
}

 
0
  1. W wczytaj_macierz() tworzysz dwie lokalne tablice macierz[] i macierzT[] a potem odwołujesz się do nich w pozostałych metodach - błąd kompilacji.
  2. Znów wczytaj_macierz(): skoro m i n ustawiasz w tej metodzie, to po co ona pobiera parametry? Może chodziło ci, żeby m i n były składowymi klasy macierz?
  3. cin>>n, cin>>m, double macierz[n][m];, double macierzT[m][n] - podobno gcc (nie wiem, nie używam) przełknie coś takiego. W innych kompilatorach, jesli wielkość tablicy jest znana podczas uruchomienia programu, to musisz użyć new/malloc do alokacji pamięci i delete[]/free do zwolnienia. Dodatkowo w zadaniu jest napisane wprost, że macierz ma mieć wymiary 3x3, więc te linie z "cin" nie są potrzebne.
  4. wywolania metod w main() to już prawdziwy kosmos :) Albo są to metody statyczne, wtedy wywolujesz je bez "void", albo niestatyczne, a wtedy napierw musisz utworzyć obiekt klasy macierz i na nim wywoływać metody. Poza tym nie widzę w klasie sekcji "public", więc domyslnie wszystkie te metody są prywatne.
  5. Nie widzę konstruktora i destruktora klasy (nie jest jawnie wymagany, ale gdy będziesz alokowac pamięć dynamicznie, może być użyteczny, żeby obiekt posprzątał po sobie).
  6. ogólna uwaga - skoro masz błąd kompilacji, to czemu go nie dodałaś pod swoim kodem. Znacznie ułatwia analizę problemu.

EDIT:
7. brakuje kończącej klamry klasy macierz:
class macierz
{
void wczytaj_macierz(int n , int m)
{
}

......... - pozostałe metody

}; <------- brakuje tego

i nie zgadzają ci się klamry {/} w metodzie wypisz_macierz() - usuń tą otwierającą przed
cout << "Macierz transponowana:" << endl;

0

Widać, że nie masz totalnie pojęcia o programowaniu, ale na szczęście widać, że coś robisz, a nie prosisz o gotowca jak większość.

 
#include<iostream>
 
using namespace std;
 
class macierz /*sprawdz, gdzie kończy się klamra klasy */
{ /*-----1-----*/
 void wczytaj_macierz(int n , int m)
{/*-----2-----*/
 
  cout << "Liczba wierszy: ";
   cin >> n;
   cout << "Liczba kolumn: ";
   cin >> m;
   double macierz[n][m];
   double macierzT[m][n];
 
   for(int i = 0; i < n; i++) //wstawianie danych
   {/*-----3-----*/
       for(int j = 0;j < m; j++)
       {/*-----4-----*/
         cout << "Wyraz [" << i << "][" << j << "]: "; 
         cin >> macierz[i][j];   cin.get();
       }   /*-----4-----*/
   }/*-----3-----*/  cin.get();
}/*-----2-----*/
void transponuj_macierz(int n, int m)
{   /*-----2-----*/
   for(int i = 0; i < n; i++) //transponowanie macierzy
   {/*-----3-----*/
       for(int j = 0;j < m; j++)
         macierzT[j][i]=macierz[i][j];
   }/*-----3-----*/
}/*-----2-----*/
void wypisz_macierz(int n , int m)
{  /*-----2-----*/
   cout << "Macierz:" << endl;
   for(int i = 0; i < n; i++) //wyswietlanie macierzy
   {/*-----3-----*/
       for(int j = 0;j < m; j++)
       {/*-----4-----*/
         cout << macierz[i][j] << " ";
       }/*-----4-----*/
       cout << endl;
   }/*-----3-----*/
 
   cout << endl;
 
{  /*-----3-----*/
   cout << "Macierz transponowana:" << endl;
   for(int i = 0; i < m; i++) //wyswietlanie macierzy transponowanej
   {/*-----4-----*/
       for(int j = 0;j < n; j++)
       {/*-----5-----*/
         cout << macierzT[i][j] << " ";
       }/*-----5-----*/
       cout << endl;
   }/*-----4-----*/
}/*-----3-----*/ // koniec funkcji wypisz_macierz  //
/*a gdzie zakończenie klamry /*-----2-----*/ i /*-----1-----*/? Przy czym /*-----1-----*/ ze średnikiem */
 
int main()
{
void macierz:: wczytaj_macierz(int n , int m)      /*podobnie do tego co tutaj jest wywołuje się funkcje statyczne klasy, niestety takich nie masz*/
 
void macierz transponuj_macierz(int n , int m)  /*Chcesz zdefiniować kolejne funkcje, czy chcesz je wywołać?*/
 
void macierz wypisz_macierz(int n , int m)
cin.get();
   return 0;
}

Do transponowania macierzy nie jest potrzebne aż dwie macierze. W C++ jest funkcja swap, która zamienia wartości obiektów, czyli swap(x, y); będzie oznaczało, że y będzie miał tą wartość którą miał x a x będzie miał wartość która miał y;
Dlatego:

void transponowanie_macierzy(double**& matrix, int size)
{
     for(int i = 0; i < size; ++i)
          for(int j = i + 1; j < size; ++j)
               swap(matrix[i][j], matrix[j][i]);
}

Poza tym, wstawianie ciała funkcji w definicji klasy, jest błędne, gdyż funkcje te stają się Od razu funkcjami inline (czyli nie posiadają adresu, tylko wstawiają kod w miejsce ich wywołania). Funkcje inline natomiast powinny być (jak sama nazwa wskazuje) zapisane w jednej linii (co oczywiście nie znaczy, żeby zapisać cały kod w jednej linii oddzielony średnikami ;). Dlatego definicje funkcji zapisuje się poniżej definicji klasy, a jeszcze lepiej w oddzielnym pliku .cpp.
Proponuję zacząć pisanie klasy od samego początku. I zaczynać stopniowo:

  1. Tworzymy klasę macierz
class macierz
{
};
  1. Co ta klasa powinna zawierać
class macierz
{
private:
     int m_size; // wystarczy tylko size, bo napisałaś, że ta macierz ma być 3x3. Pytanie tylko czy tworzona dynamicznie, czy na sztywno, zakładam, że dynamicznie
     double** m_matrix;
public:
     macierz(int = 3); // konstruktor
     ~macierz(); // destruktor
     
     void matrix_init();
     void matrix_display();
     void matrix_transposition();
};

macierz::macierz(int size) : m_size(size)
{
     m_matrix = new double*[m_size];
     
     for(int i = 0; i < m_size; ++i)
          m_matrix[i] = new double[m_size];
}

macierz::~macierz()
{
     for(int i = 0; i < m_size ++i)
          delete [] m_matrix[i];

     delete [] m_matrix;
}

void macierz::init()
{
     for(int i = 0; i < m_size; ++i)
          for(int j = 0; j < m_size; ++j)
          {
               cout << "Wprowadz wartosc dla MATRIX[ " << i << " ][ " << j << " ] : ";
               double temp;
               cin >> temp;
               m_matrix[i][j] = temp;
          }
}

Dalej myślę, że poradzisz sobie sama z definicją funkcji.

Jeżeli miało to być na sztywno, wtedy nie potrzebne będą konstruktor i destruktor

class macierz
{
private:
     m_matrix[3][3];
public:
     void matrix_init();
     void matrix_display();
     void matrix_transposition();
};

void macierz::init()
{
     for(int i = 0; i < 3; ++i)
          for(int j = 0; j < 3; ++j)
          {
               cout << "Wprowadz wartosc dla MATRIX[ " << i << " ][ " << j << " ] : ";
               double temp;
               cin >> temp;
               m_matrix[i][j] = temp;
          }
}
0

dzięki że pomagasz:). Załużmy że chce zrobić dynamicznie zrobiłam według twoich wskazówek ale nie wiem czy dobrze no i pojawia się błąd jeszcze w twoim kodzie(błąd z instrukcją size). Nie wiem czemu bo w tych klasach jestem zagubiona trochę.

Taki kod zrobiłam:


#include <iostream>
using namespace std;
class macierz
{
private:
     int m_size; // wystarczy tylko size, bo napisałaś, że ta macierz ma być 3x3. Pytanie tylko czy tworzona dynamicznie, czy na sztywno, zakładam, że dynamicznie
     double** m_matrix;
public:
     macierz(int = 3); // konstruktor
     ~macierz(); // destruktor
 
     void  wczytaj_macierz();
     void  transponuj_macierz();
     void  wypisz_macierz();
};
 
macierz::macierz(int size) : m_size(size)
{
     m_matrix = new double*[size];
 
     for(int i = 0; i < size; ++i)
          m_matrix[i] = new double[size];
}
 
macierz::~macierz()
{
     for(int i = 0; i < size ++i)
          delete [] m_matrix[i];
 
     delete [] m_matrix;
}
 
void macierz::wczytaj_macierz()
{
     for(int i = 0; i < size; ++i)
          for(int j = 0; j < size; ++j)
          {
               cout << "Wprowadz wartosc dla MATRIX[ " << i << " ][ " << j << " ] : ";
               double temp;
               cin >> temp;
               m_matrix[i][j] = temp;
          }
void macierz::transponuj_macierz()
{   
   for(int i = 0; i < size; i++) //transponowanie macierzy
   {
       for(int j = 0;j < size; j++)
         m_matrix[i][j] = temp;
   }
}

void macierz::wypisz_macierz()
{  
   cout << "Macierz:" << endl;
   for(int i = 0; i < size; i++) //wyswietlanie macierzy
   {
       for(int j = 0;j < size; j++)
       {
         cout << m_matrix[i][j] << " ";
       }
       cout << endl;
   }
 
   cout << endl;
 
{  
   cout << "Macierz transponowana:" << endl;
   for(int i = 0; i < size; i++) //wyswietlanie macierzy transponowanej
   {
       for(int j = 0;j < size; j++)
       {
         cout << m_matrix[i][j] << " ";
       }
       cout << endl;
   }
} // koniec funkcji wypisz_macierz  //

int main()
{
wczytaj_macierz()      
 
void macierz transponuj_macierz()  
 
void macierz wypisz_macierz()
cin.get();
   return 0;
}
 
0

Błąd jest dokładnie tu:

 
 for(int i = 0; i < size; ++i)
0

Poprawiłem mój kod. We wszystkich miejscach gdzie jest size trzeba zmienić na m_size, oprócz miejsca w konstruktorze (int size) : m_size(size). Pisałem to na forum od razu i nie sprawdziłem.

Zobacz jak wygląda twoja funkcja transponowania macierzy

void macierz::transponuj_macierz()
{   
   for(int i = 0; i < size; i++) //transponowanie macierzy
   {
       for(int j = 0;j < size; j++)
         m_matrix[i][j] = temp;
   }
}<cpp>
Dlaczego wkladasz definicje funkcji do funkcji wczytaj macierz? Przez to że wstawiłaś tam kod znowu nie zamknięte są klamry.
Każda funkcja ma być osobno, najlepiej 2 lub 3 entery niżej, wtedy widzisz co się dzieje.
Pozatym, sprawdz twoją funkcję transponuj_macierz z moją, którą wstawiłem na początku mojego poprzedniego posta.

Przy wypisywaniu macierzy w funkcji wypisz_macierz musisz wywołać metodę transponowania macierzy po wypisaniu macierzy po raz pierwszy. Wtedy macierz się transponuje i wypisujesz jeszcze raz tak jak to zrobiłaś

W funkcji main() musisz najpierw stworzyć obiekt tej klasy którą stworzyłaś i wtedy metody wywołujesz:
<cpp>int main()
{
     macierz m;

     m.wczytaj_macierz();

     m.wypisz_macierz();
}

Chociaż ja zrobiłbym tak, że funkcję wypisz_macierz ograniczyłbym tylko do wypisywania macierzy, a w funkcji transponuj_macierz wprowadziłbym cout który napisałby "Zaszła transponacja macierzy" i wtedy wypisałbym ją jeszcze raz niżej

0

No zrobiłam takie coś ale nadal się nie kompliluje. Poza tym zmniejszyłam kod aby od razu pokazywał mi transponowaną macierz (bez tej którą podam).


#include <iostream>
#include <string>
using namespace std;
class macierz
{
private:
     int m_size; // wystarczy tylko size, bo napisałaś, że ta macierz ma być 3x3. Pytanie tylko czy tworzona dynamicznie, czy na sztywno, zakładam, że dynamicznie
     double** m_matrix;
public:
     macierz(int = 3); // konstruktor
     ~macierz(); // destruktor
 
     void  wczytaj_macierz();
     void  transponowanie_macierzy();
     void  wypisz_macierz();
};
 
macierz::macierz(int size) : m_size(size)
{
     m_matrix = new double*[m_size];
 
     for(int i = 0; i < m_size; ++i)
          m_matrix[i] = new double[m_size];
}
 
macierz::~macierz()
{
     for(int i = 0; i < m_size; ++i)
          delete [] m_matrix[i];
 
     delete [] m_matrix;
}
 
void macierz::wczytaj_macierz()
{
     for(int i = 0; i < m_size; ++i)
          for(int j = 0; j < m_size; ++j)
          {
               cout << "Wprowadz wartosc dla MATRIX[ " << i << " ][ " << j << " ] : ";
               double temp;
               cin >> temp;
               m_matrix[i][j] = temp;
          }
}

void transponowanie_macierzy(double**& matrix, int m_size)
{
	cout<<"Zaszla transpozycja macierzy";
     for(int i = 0; i < m_size; ++i)
          for(int j = i + 1; j < m_size; ++j)
               swap(matrix[i][j], matrix[j][i]);
               
}

void macierz::wypisz_macierz()
{  
  
cout << "Macierz transponowana:" << endl;
   for(int i = 0; i < m_size; i++) //wyswietlanie macierzy transponowanej
   {
       for(int j = 0;j < m_size; j++)
       {
         cout << m_matrix[i][j] << " ";
       }
       cout << endl;
   }
}; // koniec funkcji wypisz_macierz  //

int main()
{ macierz m;

     m.wczytaj_macierz();
     transponowanie_macierzy();
     m.wypisz_macierz();


   return 0;
}
 

No i w tym nie wiem czy zmieniać size na m_size ponieważ gdy nie zmieniam to błąd nie wyskakuje no i gdy zmienie też błąd nie wyskakuje.


macierz::macierz(int size) : m_size(size)
{
     m_matrix = new double*[size];
 
     for(int i = 0; i < size; ++i)
          m_matrix[i] = new double[size];
}

 
0

Nie wyskakuje, bo size jest parametrem funkcji. Tworzy sie on na stosie, jest widoczny tylko w obrebie tej funkcji i jest niszczony po wyjaciu. Akurat w tym przypadku moze zostac, ale skoro m_size ma ta sama wartosc a nalezy do tej klasy, to warto zmienic (ale powtarzam, nie musisz)

W funkcji main wywolaj funkcje tak:

int main()
     macierz m;
     m.wczytaj_macierz();
     m.wypisz_macierz();
     m.transponuj_macierz();
     m.wypisz_macierz();

     getchar(); // wstrzymanie obrazu
     return 0;
}
0

tak właśnie wywołuję i nic :). Ty nie dałeś klamry po int main() i i błąd wyskakiwał. A gdy daje klamrę to się nie kompiluje wcale. Może jakąś biblioteke zastosować???

Robię w programie Dev-C++.

Chyba że jakiś inny błąd tak aktualnie wygląda program:

 
#include <iostream>

using namespace std;
class macierz
{
private:
     int m_size; // wystarczy tylko size, bo napisałaś, że ta macierz ma być 3x3. Pytanie tylko czy tworzona dynamicznie, czy na sztywno, zakładam, że dynamicznie
     double** m_matrix;
public:
     macierz(int = 3); // konstruktor
     ~macierz(); // destruktor
 
     void  wczytaj_macierz();
     void  transponowanie_macierzy();
     void  wypisz_macierz();
};
 
macierz::macierz(int size) : m_size(size)
{
     m_matrix = new double*[m_size];
 
     for(int i = 0; i < m_size; ++i)
          m_matrix[i] = new double[m_size];
}
 
macierz::~macierz()
{
     for(int i = 0; i < m_size; ++i)
          delete [] m_matrix[i];
 
     delete [] m_matrix;
}
 
void macierz::wczytaj_macierz()
{
     for(int i = 0; i < m_size; ++i)
          for(int j = 0; j < m_size; ++j)
          {
               cout << "Wprowadz wartosc dla MATRIX[ " << i << " ][ " << j << " ] : ";
               double temp;
               cin >> temp;
               m_matrix[i][j] = temp;
          }
}
 
void transponowanie_macierzy(double**& matrix, int m_size)
{
        cout<<"Zaszla transpozycja macierzy";
     for(int i = 0; i < m_size; ++i)
          for(int j = i + 1; j < m_size; ++j)
               swap(matrix[i][j], matrix[j][i]);
 
}
 
void macierz::wypisz_macierz()
{  
 
cout << "Macierz transponowana:" << endl;
   for(int i = 0; i < m_size; i++) //wyswietlanie macierzy transponowanej
   {
       for(int j = 0;j < m_size; j++)
       {
         cout << m_matrix[i][j] << " ";
       }
       cout << endl;
   }
}; // koniec funkcji wypisz_macierz  //
 
int main()
{


     macierz  m;
     m.wczytaj_macierz();
     m.transponowanie_macierzy();
     m.wypisz_macierz();
  cin.get();
   
     return 0;
}
0

W definicji funkcji teansponowanie macierzy wywal parametry, bo ich nie potrzeba i srednik po funkcji wypisz_macierz() i teraz juz powinno dzialac. A jesli nie, to pokaz jakie bledy wywala kompilator

0

Średnik przecież mam napisany co widać na powyższym przykładzie. A błędu nie wywala właśnie tylko jak naciskam na kompilacje
to się coś tam robi ale się nie kompiluje(nie zaznacza mi żadnego błędu).

takie coś tylko:
[Linker error] C:\DOCUME1\ben\USTAWI1\Temp\cc2jKi9a.o:prawiezrobionamacierz.cpp:(.text+0x322): undefined
ld returned 1 exit status

0

ok wywaliłam parametry w funkcji transponuj macierz oraz usunełam średnik.
Dopisałam też w funkcji transponuj macierz :

 
void macierz:: transponowanie_macierzy()

ale teraz mam błąd w

 
   swap(matrix[i][j], matrix[j][i]);

a jeżeli zrobię

 
void transponowanie_macierzy()

to mam błąd w

 
 for(int i = 0; i < m_size; ++i)
0
void macierz::transponowanie_macierzy()
0

wszystko działa musiałam wszędzie napisać m_macierz dzięki wielkie za pomoc :* bardzo pomogłeś mi:)

1 użytkowników online, w tym zalogowanych: 0, gości: 1