Witam. Mam problem z przeciążaniem operatorów, a mianowicie zadaniem jest utworzenie Drzewa, które będzie się składało z obecnego drzewa połączonego z nowym drzewem
( this = this + noweDrzewo)
W dolaczDrzewoDoDrzewa zatrzymuje się na linijce "*this = *this + drzewoDoDolaczenia;" w tej linijce przechodzi do przeciazania +, ale wychodzi błąd przy "return noweDrzewo;", bo nie wchodzi juz dalej do " = " .
Wychodzi błąd:
Zgłoszono wyjątek: naruszenie dostępu do odczytu.
std::_Vector_alloc<std::_Vec_base_types<Node *,std::allocator<Node *> > >::_Mylast(...) zwrócił 0x90959D7C.
i pokazuje klase vector i w niej wskazuje na błąd tutaj:
size_type size() const _NOEXCEPT
{ // return length of sequence
return (static_cast<size_type>(this->_Mylast() - this->_Myfirst()));
}
void Drzewo::dolaczDrzewoDoDrzewa(vector<string> nowaKomenda)
{
Drzewo drzewoDoDolaczenia;
drzewoDoDolaczenia.ustawKorzen(*drzewoDoDolaczenia.utworzDrzewo(0, nowaKomenda));
drzewoDoDolaczenia.ustawWektorKomendaUzytkownika(nowaKomenda);
*this = *this + drzewoDoDolaczenia;
}
/*__________PRZECIAZANIE__OPERATOROW_____________________*/
Drzewo Drzewo::operator+(Drzewo drzewoDoDodania)
{
vector<string> stringKomendaZDrzewaDoDodania = drzewoDoDodania.getWektorKomendaUzytkownika();
vector<string> stringKomendaObecnegoDrzewa = getWektorKomendaUzytkownika();
vector<string> komendaDlaNowegoDrzewa = utworzNowaKomende(stringKomendaObecnegoDrzewa, stringKomendaZDrzewaDoDodania);
Drzewo noweDrzewo;
noweDrzewo.ustawKorzen(*noweDrzewo.utworzDrzewo(_WARTOSC_ZERO, komendaDlaNowegoDrzewa));
noweDrzewo.ustawWektorKomendaUzytkownika(komendaDlaNowegoDrzewa);
return noweDrzewo;
}
void Drzewo::operator=(Drzewo drzewoDoSkopiowania)
{
Node* nowyKorzen = new Node(*drzewoDoSkopiowania.korzen);
if (this->korzen != nullptr) delete[] korzen;
this->ustawKorzen(*nowyKorzen);
}
//*/
#pragma once
#include "Stale.h"
class Node
{
public:
friend class Drzewo;
friend class Interface;
Node();
Node(string wartosc);
Node(Node &node);
~Node();
void setWartosc(string war);
void setWynik(double nowyWynik);
double wyliczWynik();
void dodajDziecko(Node &noweDziecko);
void vSetVarVal(string wartosc, int wynik);
string toString();
string getWartosc();
double getWynik();
bool isNumber();
private:
double wynik;
string wartosc;
vector<Node*> dzieci;
int ileDzieci;
};//class Node
#include "Node.h"
Node::Node()
{
wartosc = _PUSTO;
wynik = _DOUBLE_ZERO;
}
Node::Node(string wart) : wartosc(wart)
{
if (!isNumber()) wynik = _DOUBLE_ZERO;
if (isNumber()) //przypisuje wynik dla liczb
{
double wynik1 = _DOUBLE_ZERO;
istringstream iss(wartosc);
iss >> wynik1;
wynik = wynik1;
}
}
Node::Node(Node & node)
{
wynik = node.getWynik();
wartosc = node.getWartosc();
ileDzieci = node.ileDzieci;
for (int i = _WARTOSC_ZERO; i < node.dzieci.size(); i++)
{
Node* dziecko = new Node(*node.dzieci[i]);
dzieci.push_back(dziecko);
}
}
Node::~Node()
{
for (int i = _WARTOSC_ZERO; i < dzieci.size(); i++)
{
delete dzieci[i];
}
}
void Node::setWartosc(string war)
{
this->wartosc = war;
}
void Node::setWynik(double nowyWynik)
{
wynik = nowyWynik;
}
string Node::getWartosc()
{
return wartosc;
}
double Node::getWynik()
{
return wynik;
}
void Node::dodajDziecko(Node &noweDziecko) //dodaje dziecko do wektora dzieci
{
dzieci.push_back(&noweDziecko);
}
void Node::vSetVarVal(string nowaWartosc, int nowyWynik) //ustawia wartosc dla zmiennych
{
if (nowaWartosc == wartosc) wynik = nowyWynik;
for (int i = 0; i < dzieci.size(); i++)
dzieci[i]->vSetVarVal(nowaWartosc, nowyWynik);
}
string Node::toString() //wyswietla informacje o wszystkich Node'ach drzewa
{
string calyString = "";
calyString += wartosc;
calyString += _PUSTY_STRING;
for (int i = 0; i<dzieci.size(); i++)
{
calyString += dzieci[i]->toString();
}
return calyString;
}
bool Node::isNumber() //sprawdza czy dany obiekt jest liczba
{
for (int i = _WARTOSC_ZERO; i < 10000; i++)
{
stringstream ss;
ss.clear();
ss << i;
string wartoscI = ss.str();
if (wartosc == wartoscI)
{
wynik = i; //przypisujemy wartosc podana przez uzytkownika
return true;
}
}
return false;
}
//oblicza wynik rownania
double Node::wyliczWynik()
{
double nowyWynik = 0.0;
if (wartosc == _PLUS ) //dla plusa
{
for (int i = _WARTOSC_ZERO; i < dzieci.size(); i++)
{
if (i == _WARTOSC_ZERO)
nowyWynik += (*dzieci[i]).wynik;
else
nowyWynik += (*dzieci[i]).wynik;
}
}
else if (wartosc == _MINUS) //dla minusa
{
for (int i = _WARTOSC_ZERO; i < dzieci.size(); i++)
{
if (i == _WARTOSC_ZERO)
nowyWynik += (*dzieci[i]).wynik;
else
nowyWynik -= (*dzieci[i]).wynik;
}
}
else if (wartosc == _PODZIEL) //dla dzielenia
{
for (int i = _WARTOSC_ZERO; i < ileDzieci; i++)
{
if (i == _WARTOSC_ZERO)
nowyWynik = (*dzieci[i]).wynik;
else
nowyWynik /= (*dzieci[i]).wynik;
}
}
else if (wartosc == _RAZY) //dla mnozenia
{
for (int i = _WARTOSC_ZERO; i < dzieci.size(); i++)
{
if (i == _WARTOSC_ZERO)
nowyWynik = (*dzieci[i]).wynik;
else
nowyWynik *= (*dzieci[i]).wynik;
}
}
else if (wartosc == _SIN) //dla sinusa
{
nowyWynik = sin((*dzieci[_WARTOSC_ZERO]).wynik);
}
else if (wartosc == _COS) //dla cosinusa
{
nowyWynik = cos((*dzieci[_WARTOSC_ZERO]).wynik);
}
else if (wartosc == "++") //dla superDodawania
{
for (int i = 0; i < dzieci.size(); i++)
{
nowyWynik += (*dzieci[i]).wynik;
}
}
return nowyWynik;
}
#pragma once
#pragma once
#include "Node.h"
class Drzewo
{
public:
friend class Interface;
Drzewo();
Drzewo(Node &korzen);
Drzewo(Drzewo &drzewo);
~Drzewo();
Drzewo operator+ (Drzewo drzewoDoDodania);
void operator= (Drzewo drzewoDoDodania);
//*/
bool czyUtworzoneDrzewo();
bool czyWWektorzeZmiennych(string wartosc);
bool czyLiczba(string stringDoSprawedzenia);
bool czyZmienna(string stringDoSprawedzenia);
bool czyFunkcja(string stringDoSprawedzenia);
bool czyOperacja(string stringDoSprawedzenia);
bool czySuperPlus(string stringDoSprawedzenia);
void ustawKorzen(Node &node);
void ustawUtworzoneDrzewo();
void ustalWynik(vector<string> wektorKomendaUzytkownika);
double wywolajObliczenieDrzewa();
string wyswitlWektorZmiennych();
string print();
//string drukuj(Node& node);
Node* utworzDrzewo(int, vector<string>wektorKomendaUzytkownika);
int ileDzieci(string wartosc);
//int getIleZmiennych();
double obliczanieWynikuDzialania(Node& node);
//double zwrocWynikRownania(Node& node);
void znajdzIUstawWynikZmiennych(string wartosc, double wynik);
void ustawWektorKomendaUzytkownika(vector<string>wektorKomendaUzytkownika);
vector<string> getWektorKomendaUzytkownika();
vector<string> utworzNowaKomende(vector<string>wektorKomendaUzytkownika1, vector<string>wektorKomendaUzytkownika2);
void dolaczDrzewoDoDrzewa(vector<string>wektorKomendaUzytkownika);
//void dodajZmiennaDoWektoraZmiennych(string nowaZmienna);
private:
bool czyUtworzone;
Node* korzen;
int ileZapisano; //UZYWANE DO TWORZENIA DRZEWA ZE STRINGA
double wynik;
vector<string> komendaUzytkownikaWDrzewie;
vector<string> wektorZmiennych;
};//class Drzewo
#include "Drzewo.h"
Drzewo::Drzewo()
{
korzen = new Node();
ileZapisano = _WARTOSC_ZERO;
czyUtworzone = _FALSE;
}
Drzewo::Drzewo(Node &korzen)
{
this->korzen = new Node(korzen);
}
Drzewo::Drzewo(Drzewo & drzewo)
{
korzen = new Node(*drzewo.korzen);
for (int i = 0; i < drzewo.komendaUzytkownikaWDrzewie.size(); i++)
{
string* nowe = &drzewo.komendaUzytkownikaWDrzewie[i];
komendaUzytkownikaWDrzewie.push_back(*nowe);
}
cout<<komendaUzytkownikaWDrzewie.size()<<endl;
czyUtworzone = _TRUE;
}
Drzewo::~Drzewo()
{
delete[] korzen;
}
/*__________PRZECIAZANIE__OPERATOROW_____________________*/
Drzewo Drzewo::operator+(Drzewo drzewoDoDodania)
{
vector<string> stringKomendaZDrzewaDoDodania = drzewoDoDodania.getWektorKomendaUzytkownika();
vector<string> stringKomendaObecnegoDrzewa = getWektorKomendaUzytkownika();
vector<string> komendaDlaNowegoDrzewa = utworzNowaKomende(stringKomendaObecnegoDrzewa, stringKomendaZDrzewaDoDodania);
Drzewo noweDrzewo;
noweDrzewo.ustawKorzen(*noweDrzewo.utworzDrzewo(_WARTOSC_ZERO, komendaDlaNowegoDrzewa));
noweDrzewo.ustawWektorKomendaUzytkownika(komendaDlaNowegoDrzewa);
return noweDrzewo;
}
void Drzewo::operator=(Drzewo drzewoDoSkopiowania)
{
Node* nowyKorzen = new Node(*drzewoDoSkopiowania.korzen);
if (this->korzen != nullptr) delete[] korzen;
this->ustawKorzen(*nowyKorzen);
}
void Drzewo::dolaczDrzewoDoDrzewa(vector<string> nowaKomenda)
{
Drzewo drzewoDoDolaczenia;
drzewoDoDolaczenia.ustawKorzen(*drzewoDoDolaczenia.utworzDrzewo(0, nowaKomenda));
drzewoDoDolaczenia.ustawWektorKomendaUzytkownika(nowaKomenda);
*this = *this + drzewoDoDolaczenia;
}
//*/
vector<string> Drzewo::utworzNowaKomende(vector<string>pierwsza, vector<string>druga)
{
pierwsza.erase(pierwsza.end() - 1); //najpierw usuwamy ustatni element
for (int i = _WARTOSC_JEDEN; i < druga.size(); i++) //pierwszym elementem jest "enter"
{
pierwsza.push_back(druga[i]);
}
return pierwsza;
}
/*___________________________________________________________________________*/
int Drzewo::ileDzieci(string wartosc)
{
if (czyFunkcja(wartosc)) return _WARTOSC_JEDEN;
else if (czyOperacja(wartosc)) return _WARTOSC_DWA;
else if (czySuperPlus(wartosc)) return 3;
else return _WARTOSC_ZERO;
}
double Drzewo::wywolajObliczenieDrzewa()
{
return obliczanieWynikuDzialania(*korzen);
}
//przechodznie post-order
double Drzewo::obliczanieWynikuDzialania(Node &node)
{
string wartosc = (node).getWartosc();
int ileMaDzieci = ileDzieci(wartosc);
for (int i = _WARTOSC_ZERO; i < ileMaDzieci; i++)
{
ileZapisano++;
node.setWynik(obliczanieWynikuDzialania(*node.dzieci[i]));
}
if (!czyZmienna(wartosc) && !czyLiczba(wartosc)) //dodajemy do tablicy zmiennych
{
double nowyWynik = node.wyliczWynik();
node.setWynik(nowyWynik);
}
double wynik = node.getWynik();
return wynik;
}
/*___________DOPISYWANIE___WYNIKU___ZMIENNYM_________________________*/
void Drzewo::znajdzIUstawWynikZmiennych(string wartosc, double wynik)
{
korzen->vSetVarVal(wartosc, wynik);
}
void Drzewo::ustawWektorKomendaUzytkownika(vector<string> nowaKomenda)
{
komendaUzytkownikaWDrzewie = nowaKomenda;
}
vector<string> Drzewo::getWektorKomendaUzytkownika()
{
return komendaUzytkownikaWDrzewie;
}
void Drzewo::ustalWynik(vector<string> komendaUzytkownika) //////////////
{
double wynik1 = _WARTOSC_ZERO;
string str;
for (int i = _WARTOSC_JEDEN; i < komendaUzytkownika.size(); i++) //wpisywanie za pomoca przeszukiwania drzewa
{
double wynik1;
str = komendaUzytkownika[i];
istringstream iss(str);
iss >> wynik1;
//cout << wektorZmiennych[i - 1]<<" " << wynik1<< endl;
znajdzIUstawWynikZmiennych(wektorZmiennych[i - 1], wynik1);
}
}
/*______________________TWORZENIE___DRZEWA_____________________*/
void Drzewo::ustawKorzen(Node &nowyKorzen)
{
korzen = &nowyKorzen;
}
Node* Drzewo::utworzDrzewo(int ileDodano, vector<string> komendaUzytkownika)
{ //tworzenie drzewa
Node* nowyNode = new Node(komendaUzytkownika[1 + ileZapisano]);
string wartosc = (*nowyNode).getWartosc();
int ileMaDzieci = ileDzieci(wartosc);
for (int i = _WARTOSC_ZERO; i < ileMaDzieci; i++) //dodajemy dzieci
{
ileDodano++;
ileZapisano++;
nowyNode->dodajDziecko(*utworzDrzewo(ileDodano, komendaUzytkownika));
}
if (czyZmienna(wartosc)) //dodajemy do tablicy zmiennych
{
if (!czyWWektorzeZmiennych(wartosc))
{
wektorZmiennych.push_back(wartosc);
ileDodano++;
}
}
return nowyNode;
}
void Drzewo::ustawUtworzoneDrzewo() //ZANZACZAMY ZE DRZEWO UTWORZONO
{
czyUtworzone = _TRUE;
}
bool Drzewo::czyUtworzoneDrzewo() //INFORMACJA O TYM CZY UTWORZONO DRZEWO
{
return czyUtworzone;
}
/*___________________DODAWANIE_ZMIENNYCH_DO_WEKTORA_________________________*/
bool Drzewo::czyWWektorzeZmiennych(string wartosc) //
{
for (int i = _WARTOSC_ZERO; i < wektorZmiennych.size(); i++)
if (wektorZmiennych[i] == wartosc) return _TRUE;
return _FALSE;
}
string Drzewo::wyswitlWektorZmiennych() //wyswietl wszystkie zmienne (string)
{
string zmienne = _ZMIENNE;
for (int i = _WARTOSC_ZERO; i < wektorZmiennych.size(); i++)
{
zmienne += wektorZmiennych[i];
zmienne += _PUSTY_STRING;
}
return zmienne;
}
string Drzewo::print() //wydrukuj cale drzewo (string)
{
string doWydrukowania;
doWydrukowania += korzen->toString();
//cout << "korzen " << korzen->getWartosc();
//cout << korzen->toString()<<endl;
return doWydrukowania;
}
bool Drzewo::czyLiczba(string sprawdz) //nie ma dzieci
{
for (char znak : sprawdz) {
if (znak < _CHAR_JEDEN || znak > _CHAR_DZIEWIEC) { return _FALSE; }
}
return _TRUE;
}
bool Drzewo::czyZmienna(string sprawdz) //nie ma dzieci
{
for (char znak : sprawdz) {
if (znak >= _CHAR_A && znak <= _CHAR_Z || znak >= _CHAR_a && znak <= _CHAR_z) { return _TRUE; }
}
return _FALSE;
}
bool Drzewo::czyFunkcja(string sprawdz) //ma jedno dziecko!
{
if (sprawdz == _SIN || sprawdz == _COS) return _TRUE;
return _FALSE;
}
bool Drzewo::czyOperacja(string sprawdz) //ma dwoje dzieci
{
if (sprawdz == _PLUS || sprawdz == _MINUS || sprawdz == _PODZIEL || sprawdz == _RAZY) return _TRUE;
return _FALSE;
}
bool Drzewo::czySuperPlus(string sprawdz) //ma trojke dzieci
{
if (sprawdz == "++") return _TRUE;
return _FALSE;
}
//Main.cpp
#include "Drzewo.h"
int main()
{
Node* node = new Node("+");
Node* node1 = new Node("1");
Node* node2 = new Node("2");
node->dodajDziecko(*node1);
node->dodajDziecko(*node2);
cout<<node->toString()<<endl;
cout <<"wynik: " <<(*node).wyliczWynik()<<endl;
//_________TWORZENIE__DRZEWA________ENTER________________
string plus = "+";
string jeden = "1";
string dwa = "2";
vector<string> komendeUzytkownika;
komendeUzytkownika.push_back("enter");
komendeUzytkownika.push_back(plus);
komendeUzytkownika.push_back(jeden);
komendeUzytkownika.push_back("-");
komendeUzytkownika.push_back("5");
komendeUzytkownika.push_back("4");
Drzewo drzewo;
drzewo.ustawKorzen(*drzewo.utworzDrzewo(0, komendeUzytkownika));
drzewo.ustawWektorKomendaUzytkownika(komendeUzytkownika);
//_________WYSWIETLANIE__DRZEWA________PRINT________________
cout << drzewo.print()<<endl;
//cout<<drzewo.czyWWektorzeZmiennych("a")<<endl; //wynik 1 - jest
//_________WYSWIETLANIE__ZMIENNYCH________VARS________________
//cout<<drzewo.wyswitlWektorZmiennych();
//_________WYLICZANIE__WARTOSCI__DRZEWA________COMP________________
vector<string> komendaZeZmiennymi;
//komendaZeZmiennymi.push_back("vars");
//komendaZeZmiennymi.push_back("5");
drzewo.ustalWynik(komendaZeZmiennymi);
double wynik = drzewo.wywolajObliczenieDrzewa();
cout << wynik << endl;
//_________DOLACZANIE__DRZEWA________JOIN________________
vector<string> wektorNowegoDrzewa;
wektorNowegoDrzewa.push_back("enter");
wektorNowegoDrzewa.push_back("+");
wektorNowegoDrzewa.push_back("1");
wektorNowegoDrzewa.push_back("2");
Drzewo drzewo2;
drzewo2.ustawKorzen(*drzewo2.utworzDrzewo(0, wektorNowegoDrzewa));
drzewo2.ustawWektorKomendaUzytkownika(wektorNowegoDrzewa);
cout << drzewo2.print();
Drzewo drzewo3 = drzewo;
drzewo.dolaczDrzewoDoDrzewa(wektorNowegoDrzewa); // drzewo = drzewo + drzewo2
system("pause");
return 0;
}
#pragma once
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<cstring>
#include<istream>
#include<vector>
#define _STALA_POJEMNOSC_TABLICY 6
#define _WARTOSC_ZERO 0
#define _WARTOSC_MINUS_JEDEN -1
#define _WARTOSC_JEDEN 1
#define _WARTOSC_DWA 2
#define _CHAR_JEDEN '1'
#define _CHAR_A 'A'
#define _CHAR_a 'a'
#define _CHAR_Z 'Z'
#define _CHAR_z 'z'
#define _ENTER_1 "1. enter <formula> \n"
#define _VARS_2 "2. vars \n"
#define _PRINT_3 "3. print \n"
#define _COMP_4 "4. comp <var0> <var2> .. \n"
#define _JOIN_5 "5. join<formula> \n"
#define _EXIT_6 "6. exit \n"
#define _DOUBLE_JEDEN 1.0
#define _DOUBLE_ZERO 0.0
#define _STRING_JEDEN "1"
#define _STRING_DWA "2"
#define _STRING_TRZY "3"
#define _STRING_CZTERY "4"
#define _STRING_PIEC "5"
#define _STRING_SZESC "6"
#define _STRING_SIEDEM "7"
#define _STRING_OSIEM "8"
#define _CHAR_DZIEWIEC '9'
#define _STRING_DZIESIEC "10"
//interface
#define _ENTER "enter"
#define _VARS "vars"
#define _PRINT "print"
#define _COMP "comp"
#define _JOIN "join"
#define _EXIT "exit"
#define _ZNAK_WIEKSZOSCI "\n>>>"
#define _ZMIENNE "zmienne: "
#define _NAZWA_DOMYSLNA "def_name"
#define _DODAJ_COPY "_copy"
#define _PUSTY_STRING " "
#define _PUSTO "";
#define _UTWORZONO "utworzono: "
#define _WYSWIETL_SIZE " size: ["
#define _ZAKONCZ_SIZE "]"
#define _PLUS "+"
#define _MINUS "-"
#define _RAZY "*"
#define _PODZIEL "/"
#define _SIN "sin"
#define _COS "cos"
#define _NAZWA_MINUS "minus "
#define _NEW_LINE "\n"
#define _WYSWIETL_LEN "len: "
#define _WYSWIETL_VALUES "values: "
#define _PRZECINEK ","
#define _FALSE false
#define _TRUE true
#define _NULL_POINTER nullptr
//bledy:
#define _UTWORZ_DRZEWO "UTWORZ NAJPIERW DRZEWO\n"
#define _BLEDNA_KOMENDA "NIE ROZPOZNANO KOMENDY\n"
#define _ZLE_ZMIENNE "nie podales zadnych zmiennych"
#define _ZLA_LICZBA "WPROWADZONO BLEDNA LICZBE\n"
#define _POPRAWIONO "\nbledne wyrazenie\npoprawiono na:\n "
using namespace std;