Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

m4rv1n
Użytkownik
Użytkownik
Posty: 5
Rejestracja: 15 maja 2011, o 20:33
Płeć: Mężczyzna
Lokalizacja: Lublin

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: m4rv1n »

Program oblicza układy równań do 10 niewiadomych za pomocą rozwinięcia Laplace'a.
Do tego celu wykorzystuję rekurencyjną funkcję det.

a - liczba niewiadomych i liczba równań
tablica[a][a] - współczynniki przy niewiadomych
wiersz - numer wiersza, w ktorym zaczyna sie podmacierz
kolumna - numery kolumn, które zawiera podmacierz
dodatkowa - dynamiczny wektor kolumn
m - mnożnik, pełni funkcję (-1) ^{i+j}
s-suma iloczynów
w-wyznacznik główny

Tutaj jest jego część, która powinna obliczać wyznacznik główny, a tymczasem wyskakuje błąd:

Kod: Zaznacz cały

206 ...a\Documents\C++\Wyznaczniki.cpp cannot convert `int (*)[((unsigned int)((int)a))]' to `int**' for argument `4' to `double det(int, int, int*, int**)' 
.

Kod: Zaznacz cały

#include <iostream>
#include <conio.h>
#include <iomanip>
#include <cstdlib>
using namespace std;

double det(int a, int wiersz, int * kolumna, int ** tablica)
{
  int g,h,k,m,* dodatkowa;
  double s;
  if(a == 1)
  {                                    // sprawdzamy warunek zakończenia rekurencji
    return tablica[wiersz][kolumna[0]];                         // macierz 1 x 1, wyznacznik równy elementowi
  }
  else
  {
    int dodatkowa[a-1];                    
    s = 0;                                
    m = 1;                                 
    for(g = 0; g < a; g++)        
          {
          k = 0;                         
          for(int h = 0; h < a - 1; h++)   
                {
                if(k == g)
                     {k++;
                     }              
                dodatkowa[h] = kolumna[k++];  
                }
          }

          s = m * tablica[wiersz][kolumna[g]] * det(a - 1,wiersz + 1, dodatkowa, tablica);
          m = -m;                                   // kolejny mnożnik                     
   return s;
   }
}

int main()
{
    double w;
    int a, opcja;
    bool c;
    time_t b;
    srand ((int) time(&b));
    cout<<endl;
    cout<<" Program oblicza uklady rownan do 10 niewiadomych"<<endl;
    cout<<" Rownania maja postac ax+by+cz+dw=p,"<<endl;
    cout<<" gdzie {a,b,c,d,p} to zmienne,"<<endl;
    cout<<" a {x,y,z,w} niewiadome."<<endl;
    cout<<endl;
    cout<<" Z jaka iloscia niewiadomych chcesz obliczyc uklad rownan?"<<endl;
    cout<<" ";
    cin>>a;
    if(a>10||a<1)
                 {system( "cls" );
                 cout<<endl;
                 cout<<" Niewlasciwa ilosc niewiadomych."<<endl;
                 cout<<" Wprowadz jeszcze raz."<<endl;
                 main();
                 }
    int tablica[a][a], p[a];
    for (int i = 0; i < a; i++)
        {for(int j = 0; j < a; j++)
                 {tablica[i][j]=0;
                 }
        p[i]=0;
         }
    do
    {
         system ( "cls" );
         cout<<endl;
        cout<<" Chcesz?:"<< endl;
        cout<<" 1. Wlasnorecznie wpisac zmienne"<< endl;
        cout<<" 2. Wylosowac je przypadkowo z przedzialu 0-10"<< endl;
        cout<<" 3. Wylosowac je przypadkowo z przedzialu 0-100"<< endl;
        cout<<" 4. Wrocic i wybrac jeszcze raz liczbe niewiadomych."<<endl;
        cout<<" 0. Wyjsc"<< endl;
        cout<<" ";
        cin>>opcja;
        switch(opcja)
                     {case 1:for(int i = 0; i < a; ++i)
                                     {for (int j = 0; j < a; ++j)
                                          { if(j+1==a)
                                                      {cout<<" Podaj zmienna ";
                                                      switch (j+1)
                                                          {case 1:cout<<"a"; break;
                                                          case 2:cout<<"b"; break;
                                                          case 3:cout<<"c"; break;
                                                          case 4:cout<<"d"; break;
                                                          case 5:cout<<"e"; break;
                                                          case 6:cout<<"f"; break;
                                                          case 7:cout<<"g"; break;
                                                          case 8:cout<<"h"; break;
                                                          case 9:cout<<"i"; break;
                                                          case 10:cout<<"j"; break;
                                                          }
                                                      cout<<" rownania numer "<<i+1<<"."<<endl;
                                                      cout<<" ";
                                                      cin>>tablica[i][j];
                                                      cout<<" Podaj zmienna p rownania numer "<<i+1<<"."<<endl;
                                                      cout<<" ";
                                                      cin>>p[i]; 
                                                      }
                                          else
                                              { switch (j+1)
                                                      {case 1:cout<<" Podaj zmienna a rownania numer "<<i+1<<"."<<endl; break;
                                                      case 2:cout<<" Podaj zmienna b rownania numer "<<i+1<<"."<<endl; break;
                                                      case 3:cout<<" Podaj zmienna c rownania numer "<<i+1<<"."<<endl; break;
                                                      case 4:cout<<" Podaj zmienna d rownania numer "<<i+1<<"."<<endl; break;
                                                      case 5:cout<<" Podaj zmienna e rownania numer "<<i+1<<"."<<endl; break;
                                                      case 6:cout<<" Podaj zmienna f rownania numer "<<i+1<<"."<<endl; break;
                                                      case 7:cout<<" Podaj zmienna g rownania numer "<<i+1<<"."<<endl; break;
                                                      case 8:cout<<" Podaj zmienna h rownania numer "<<i+1<<"."<<endl; break;
                                                      case 9:cout<<" Podaj zmienna i rownania numer "<<i+1<<"."<<endl; break;
                                                      case 10:cout<<" Podaj zmienna j rownania numer "<<i+1<<"."<<endl; break;
                                                      }
                                              cout<<" ";
                                              cin>>tablica[i][j];
                                              }
                                          }
                                     }
                              break;
                      case 2: for (int i = 0; i < a; ++i)
                                  {for (int j = 0; j < a; ++j)
                                       { 
                                         tablica[i][j] = rand() % 10 + 1;
                                         }
                                  p[i] = rand() % 10 + 1;
                                  }
                              break;
                      case 3: for (int i = 0; i < a; ++i)
                                  {for (int j = 0; j < a; ++j)
                                       { 
                                         tablica[i][j] = rand() % 100 + 1;
                                         }
                                  p[i] = rand() % 100 + 1;
                                  }
                              break;
                      case 4: system( "cls" );
                              main();
                              break;
                      case 0: cout << "Dziekujemy :)"<<endl; 
                              break; 
                      default: cout << "Nieznana opcja!"<<endl; 
                     }
        if (opcja==1||opcja==2||opcja==3)
         {
             system( "cls" );
             cout<<endl;
             for(int i = 0; i < a; ++i)
                 {
                 cout<<" ";
                 for(int j=0; j<a; j++)
                     {
                             if(j+1==a)
                             {
                             cout<<tablica[i][j];
                             switch (j+1)
                                    {case 1:cout<<"x"; break;
                                    case 2:cout<<"y"; break;
                                    case 3:cout<<"z"; break;
                                    case 4:cout<<"w"; break;
                                    case 5:cout<<"v"; break;
                                    case 6:cout<<"u"; break;
                                    case 7:cout<<"t"; break;
                                    case 8:cout<<"s"; break;
                                    case 9:cout<<"r"; break;
                                    case 10:cout<<"q"; break;
                                    }
                             cout<<"="<<p[i];
                             }
                             else
                             {
                             cout<<tablica[i][j];
                             switch (j+1)
                                    {case 1:cout<<"x"; break;
                                    case 2:cout<<"y"; break;
                                    case 3:cout<<"z"; break;
                                    case 4:cout<<"w"; break;
                                    case 5:cout<<"v"; break;
                                    case 6:cout<<"u"; break;
                                    case 7:cout<<"t"; break;
                                    case 8:cout<<"s"; break;
                                    case 9:cout<<"r"; break;
                                    case 10:cout<<"q"; break;
                                    }
                             cout<<"+";
                             }
                     }
             cout<<endl;
             cout<<endl;
             }
          cout<<" Czy chcesz zmienic zmienne?"<<endl;
          cout<<" 1. Tak    0.Nie"<<endl;
          cout<< endl;
          cin>>c;  
        }
    }while (c!=0);
    
    cout << fixed << setprecision(2);
    int kolumna[a];
    for(int i = 0; i < a; i++)
          {
          kolumna[i] = i;
          }
          w = det(a, 0, kolumna, tablica);
    cout<<w<<endl;
    getch();
}
Gdzie leży błąd i co trzeba zrobić żeby to wyeliminować?
Z góry dzięki.
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: soku11 »

Samego kodu nie da się czytać. Po komunikacie domyślam się, że błąd jest tutaj:

Kod: Zaznacz cały

int tablica[a][a];
// ..
w = det(a, 0, kolumna, tablica);
tablica nie jest bowiem typem konwertowalnym do int**. Swoją drogą nie radziłbym używać variable length arrays tworzonych na stosie.
m4rv1n
Użytkownik
Użytkownik
Posty: 5
Rejestracja: 15 maja 2011, o 20:33
Płeć: Mężczyzna
Lokalizacja: Lublin

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: m4rv1n »

Prawdę mówiąc, niepotrzebnie wklejałem cały program, sorry.

W takim razie z jakim typem zmiennych będzie to działać?
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: soku11 »

Z dwuwymiarową tablicą stworzoną dynamicznie. Będzie to wtedy tak naprawdę tablica wskaźników, więc zadziała.
m4rv1n
Użytkownik
Użytkownik
Posty: 5
Rejestracja: 15 maja 2011, o 20:33
Płeć: Mężczyzna
Lokalizacja: Lublin

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: m4rv1n »

Dobra, dzięki. Zrobiłem jak powiedziałeś. Teraz już przyjmuje.
Wyskakuje mi tylko "W twoim programie zgłoszono naruszenie praw dostępu (błąd segmentacji).", które dotyczy linijki 34 w kodzie:

Kod: Zaznacz cały

dodatkowa[h] = kolumna[k];
Chyba jest to przepełnienie stosu.

Kod: Zaznacz cały

#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;

float det(int a, int wiersz, int * kolumna, float ** tablica)
{
  int k,m, * dodatkowa;
  float s;
  if(a == 1)                        //warunek zakonczenia rekurencji
  { 
    return tablica[kolumna[0]][wiersz]; // Zostaje nam tablica 1 elementowa, której element jest jej wyznacznikiem
                 
  }
  else
  {
    delete []dodatkowa;
    int * dodatkowa;
    dodatkowa = new int [a-1];    //deklarujemy dodatkowa dynamiczna tablice kolumn
    for(int i = 0; i<a-1; i++)
            {
                dodatkowa[i]=0;
                }
    s = 0;                                
    m = 1;                                 //mnożnik
    for(int g = 0; g < a; g++)                
          {
          for(int h = 0; h < a - 1; h++)   
                {
                if(k==g)
                     {
                     k++;
                     }
                dodatkowa[h] = kolumna[k];
                k++;
                }

          s = s + m * tablica[kolumna[g]][wiersz] * det(a - 1,wiersz + 1, dodatkowa, tablica);
          m = -m;
          delete [] dodatkowa;
          }                                               
   return s;
   }
}
Jak to pokonać?
Nie widzę możliwości zrobienia tego rekurencją ogonową. Może da się jakoś zadeklarować więcej pamięci na tą funkcję?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: Afish »

Raczej odwołujesz się do elementów spoza tablicy, przepełnienie stosu jest sygnalizowane inaczej.
m4rv1n
Użytkownik
Użytkownik
Posty: 5
Rejestracja: 15 maja 2011, o 20:33
Płeć: Mężczyzna
Lokalizacja: Lublin

Rozwinięcie Laplace'a / Problem z typami zmiennych w funkcji

Post autor: m4rv1n »

Aha. Tylko, że "kolumna" została zadeklarowana tutaj:

Kod: Zaznacz cały

float det(int a, int wiersz, int * kolumna, float ** tablica)
i wydaje mi się, że jeśli wstawiam w odwołaniu do funkcji w miejsce "int *kolumna" tablicę o nazwie "dodatkowa" to przy wykonywaniu funkcji dane z "dodatkowej" powinny się przenieść do "kolumny" i być dostępne do wywołania pod "kolumna[]".
ODPOWIEDZ