• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Mnożenie wielomianów w oparciu o funkcje przeciążającą operator?

Object Storage Arubacloud
+3 głosów
1,722 wizyt
pytanie zadane 25 kwietnia 2015 w C i C++ przez tomek.w Nowicjusz (180 p.)
Dzień dobry! Witam wszystkich na forum. To mój pierwszy post tutaj dlatego proszę o wyrozumiałość z powodu języka i braków merytorycznych.
Mam do napisania projekt "Algebra wielomianów". Jest to projekt zorientowany obiektowo (przynajmniej taki powinien być). Struktura klasy jest stosunkowo prosta. Atrybutem jest wskaźnik na dynamiczna tablicę współczynników. Tablica jest alokowana podczas wywołania konstruktora jednoargumentowego przyjmującego jego stopien wielomianu. Do operacji algebraicznych muszę wykorzystać przeciążenie operatorów.
Niewielkie trudności z dodawaniem i odejmowanie pokonałem. Niestety problem pojawił się podczas mnożenia. Spróbowałem to napisać za pomocą dwóch pętli jedna pobiera element z wielomianu pierwszego a druga mnoży ten element przez wszystkie współczynniki drugiego. Niestety problem jest oczywisty funkcja tak skonstruowana nie dodaje kolejnych wyników dla tego samego stopnia tylko przesłania ten poprzedni wynik. W Internecie są infromacje aby użyć tutaj splotu...czy to jedyna możliwość, jeśli nie to proszę o pomoc a jeśli tak to proszę pomoc jak zaimplentować ten splot. Z góry dziękuje za odpowiedź

1 odpowiedź

+1 głos
odpowiedź 25 kwietnia 2015 przez Buby Pasjonat (19,590 p.)
wybrane 26 kwietnia 2015 przez tomek.w
 
Najlepsza

Cześć! Twoje zadanie wydało mi się na tyle interesujące, że postanowiłem napisać własną wersję mnożenia wielomianu jako klasy. Cały trick bedzie polegał na tym - nasz operator mnożenia będzie zwracał nowy obiekt klasy Wielomian, którego właściwości potem przypiszemy do naszego obiektu, za pomocą przeciążonego operatora przypisania. No dobrze, więc zaczynajmy. Wiemy, że stopień naszego nowego wielomianu, będzie równy sumie stopni wielomianów będących składnikami, więc nasza tablica będzie takiej wielkości. Przemnożymy każdy przez każdy, a o wynik tego mnożenia będziemy powiększać element tablicy odpowiadający poszczególnemu stopniowi - ja wykorzystałem tutaj zmienne i oraz j, które są stopniami składników, więc stopień wyniku bedzie równy ich sumie. Reszty domyslisz się z kodu, opisałem go bardzo szczegółowo. Myśle, że mogło chodzić o taki efekt. Tak na marginesie, mógłbym się dowiedzieć na jakim etapie nauki jesteś - uczeń technikum, student, a może samouk? ;)

 

#include<iostream>
#include<ctime>
#include<cstdlib>

class Wielomian //Tworze nowa klase
{
    public:
        Wielomian( int, bool ); //prototyp konstruktora klasy, dodalem sobie przelacznik wg ktorego wypelniam tablice, badz czyscze
        static void Pokaz(Wielomian*);  // chcialem sie zabawic metoda statyczna, zwykle wyswietlanie
        int ZwrocStopien(){ return Stopien; } // praktykujac metode od szczegolu do ogolu zwracam sobie skladowe
        int *ZwrocWskaznikNaTablice(); // praktykujac metode od szczegolu do ogolu zwracam sobie skladowe

        Wielomian operator *( Wielomian Drugi ) // funkcja o ktora Ci chodzilo, zwraca nowy obiekt
        {
            int StopienNowegoWielomianu = this->Stopien + Drugi.ZwrocStopien(); // stopien nowego wielomianu tak jak pisalem wyzej
            Wielomian DoZwrotu( StopienNowegoWielomianu, true ); // tworze nowy wielomian, ktorego wspolczynniki wynosza 0

            int* Tablica = DoZwrotu.ZwrocWskaznikNaTablice(); // Chce operowac na obszarze w pamieci, w ktorym zapisane sa nowe wspolczynniki
            int* DrugieWspolczynniki = Drugi.ZwrocWskaznikNaTablice(); //Potrzebuje tez znac wspolczynniki drugiego wielomianu, aby mnozyc

            for( int i = 0; i <= Stopien; ++i ) //Przemnazam pierwszy
                for( int j = 0; j <= Drugi.ZwrocStopien(); j++ ) //Przez wszystkie elementy drugiego
                    Tablica[i+j] += Wspolczynniki[i]*DrugieWspolczynniki[j]; // zapisuje wg tego co napisalem wyzej wynik mnozenia

            return DoZwrotu; //zwracam nowy obiekt
        }

        void operator =( Wielomian Przypis ) //przeciazam operator, aby przypisac wartosci mnozenia
        {
            delete [] Wspolczynniki; //usuwam zaalokowana wczesniej pamiec

            this->Stopien = Przypis.ZwrocStopien(); //zapisuje stopien
            this->Wspolczynniki = Przypis.ZwrocWskaznikNaTablice(); //zapisuje adres na nowa tablice
        }

    private:
        int *Wspolczynniki; //skladowa tablicy wspolczynnikow
        int Stopien; //skladowa stopnia wielomianu
};

Wielomian::Wielomian( int Stopien, bool CzyPusta = false ) // konstruktor, przelacznik z domyslna wartoscia false odpowiada za wypelnienei zerami
{                                                       // w przeciwnym wypadku wylosuje sobie liczby od 1 do 5, dodalem to na potrzeby testu,
                                                        // poniewaz nie napisales skad bierzemy wartosci
    Wspolczynniki = new int[Stopien+1]; // alokacja pamieci
    this->Stopien = Stopien; //przypisanie stopnia wielomianu

    if( !CzyPusta ) // jesli ma nie byc pusta to wypelnij randomowymi liczbami 1-5
    {
        for( int i = 0; i <= Stopien; ++i )
        Wspolczynniki[i] = ( rand()%5 ) + 1;
    }
    else // jesli nie to wyzeruj wartosci wspolczynnikow
    for( int i = 0; i <= Stopien; ++i )
    Wspolczynniki[i] = 0;
}

int* Wielomian::ZwrocWskaznikNaTablice() // praktykujac metode od szczegolu do ogolu zwracam sobie skladowe
{
    return Wspolczynniki;
}

void Wielomian::Pokaz(Wielomian* Wyswietl ) //kulawe wyswietlanie na szybko, wazne ze wynik dobry
{
    int* Tablica = Wyswietl->ZwrocWskaznikNaTablice();

    for( int i = Wyswietl->Stopien; i >= 0; --i )
    {
        std::cout << "+(" << Tablica[i] << "x^" << i << ")";
    }
}

int main(void)
{
    srand( time( NULL ) ); //pseudolosowosc

    Wielomian Pierwszy( 2 ); //tworze sobie wielomian 2 stopnia
    Wielomian Drugi( 1 ); //tworze sobie wielomian 1 stopnia

    Wielomian::Pokaz(&Pierwszy); std::cout << " * "; Wielomian::Pokaz(&Drugi); //wyswietlam co mam wymnozyc
    Pierwszy = (Pierwszy*Drugi); // Przypisuje mu wartosc wymnozonego wielomianu
    std::cout << " = "; Wielomian::Pokaz( &Pierwszy ); // wyswietlam
    return 0;
}

 

komentarz 26 kwietnia 2015 przez tomek.w Nowicjusz (180 p.)

Wielkie dzięki za pomoc.
Jeśli chodzi o Twoje pytanie to studiuję, ale tak na prawdę na uczelni niewiele się nauczyłem - tam głównie nastepuje jedynie weryfikacja wiedzy.
Teraz mam pytanie odnośnie poniższego fragmentu kodu (bo wydaje mi się, że to jest najważniejsza cześć tej funkcji a nie do końca rozumiem dlaczego)

int* Tablica = DoZwrotu.ZwrocWskaznikNaTablice(); 
int* DrugieWspolczynniki = Drugi.ZwrocWskaznikNaTablice();

Dlaczego użyłeś tutaj tych wskaźników, z tego co pamiętam ja mam tylko jeden wskaźnik na pierwszy element tablicy, więc wnioskuję, że tutaj tkwił mój błąd. Możesz mi wyjaśnić dlaczego tak to zrobiłeś?

 

komentarz 26 kwietnia 2015 przez Buby Pasjonat (19,590 p.)

Już objaśniam, w tej funkcji operujemy na trzech tablicach:

  1. Pierwszą są współczynniki naszego wielomianu, których użyjemy do mnożenia.
  2. Drugą są współczynniki wielomianu, będącego argumentem funkcji, których użyjemy do mnożenia.
  3. Trzecią natomiast jest tablica wynikowa obiektu DoZwrotu, którą wypełniłem zerami, aby tylko powiększać poszczególne pola wynikami mnożenia.

Teraz kolejna sprawa, tablica to wskaźnik na pierwszy element, więc korzystając z tej wiedzy, przypisałem sobie pierwsze elementy zaalokowanych tablic do wskaźników, żeby dostać się do wartości. Korzystając z tych wartości i wiedząc, jaki rozmiar mają tablice, bazując na składowych obiektów o nazwie Stopien, tak aby nie wyjechać poza zakres tablic wykonałem mnożenie.

Jak teraz patrzę na mój kod, to powinienem stworzyć destruktor klasy, w którym usuwałbym zaalokowaną pamięć, bo akurat w tym programie, jedna tablica zostaje w pamięci nieposprzątana. Jeśli coś nadal jest zbyt zawiłe, to pisz, postaram się to opisac prostszymi słowami :)

 

Podobne pytania

0 głosów
2 odpowiedzi 194 wizyt
pytanie zadane 13 kwietnia 2021 w C i C++ przez grzecho123 Początkujący (450 p.)
0 głosów
4 odpowiedzi 580 wizyt
pytanie zadane 25 września 2017 w JavaScript przez adrian588 Początkujący (470 p.)
0 głosów
2 odpowiedzi 491 wizyt
pytanie zadane 9 czerwca 2017 w C i C++ przez niezalogowany

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...