CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Prośba o poradę

Prośba o poradę

dział ogólny

Prośba o poradę

Nowy postprzez Corvis » niedziela, 27 lutego 2011, 23:49

Witam,

Mam taki problem. W wektorze przechowuje dane o wykresach, w uproszczeniu:

KOD cpp:     UKRYJ  
enum TFunkcjeWykresu { // Typy wykresów
        tfwKurs,
        tfwRoznica,
        tfwMul,
        tfwAdd,
        tfwAbs,
        tfwMin,
        tfwMax,
        tfwIf,
        tfwFunkcja1
};

struct TWykres { // Uproszczona struktura opisująca wykres
        int Adres;
        TRodzajWykresu Rodzaj;
};

std::vector<TWykres> Wykresy; // wektor wykresów



Problem polega na tym, że funkcję tfwFunkcja1 mogę policzyć dopiero wtedy gy inne funkcje są już policzone. Przykład jak to wygląda w moim edytorze:

KOD cpp:     UKRYJ  
W1 = Random(255);
W2 = if(W1>100) // Jeżeli wartości z wykresu 1 są większe od 100 to wartości W2 = 1
W3 = Funkcja1(W2); // Oblicz Funkcje1 z W2


Problem pojawia mi się wtedy jak ktoś napisze tak:

KOD cpp:     UKRYJ  
W1 = if(W2>100);  // nie mam jeszcze wartości W2
W2 = Random(255);
W3 = Funkcja1(W2); // Oblicz Funkcje1 z W2


Wynika to z kolejności liczenia wartości dla wykresów. Robię to kolejno tak jak napisane jest w edytorze. W 1 przypadku liczę W1, W2, W3 w drugim W2 -> nie mam jeszcze W1, W1, i W3.

Zastanawiam się jak to rozwiązać. Ustalając priorytet liczenia ??? Czyli, że Funkcja1 zawsze policzy się po wszystkich innych funkcjach ?? Może mi ktoś coś doradzi ??? Jeżeli coś nie jasno napisałem to chętnie wytłumaczę dokładniej.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez Cyfrowy Baron » poniedziałek, 28 lutego 2011, 09:05

Problem polega na tym, że funkcję tfwFunkcja1 [...]


tfwFunckja1 jak wynika z Twojego kodu nie jest funkcją lecz elementem typu wyliczeniowego TFunkcjeWykresu o wartości 8.

Co do reszty to nic nie zrozumiałem... :roll:
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » poniedziałek, 28 lutego 2011, 11:02

Kurde, ostatnio mam problem z wyrażeniem tego o co mi chodzi :|

Mam wektor wykresów (funkcji) i mam wektor danych

KOD cpp:     UKRYJ  
std::vector<TTik> Dane;
std::vector<TWykres> Wykresy;

// Gdzie TTik to struktura

struct TTik {
  TDateTime DataGodzina;
  std::vector<long double> Dane;
};

// A TWykres to uproszczona struktura opisująca wykres

struct TWykres {
  int Adres;
  TRodzajWykresu Rodzaj;
};


Typ wyliczeniowy opisuje mi jakiego rodzaju wykres (funkcje) dodałem do wektora Wykresy. Pole Adres w strukturze TWykres opisuje pozycję komórki w której znajdują się obliczenia danego wykresu (funkcji).

Jeżeli Dodam do wykresów coś takiego;

KOD cpp:     UKRYJ  
TWykres wykres0;
wykres1.Adres = 0;
wykres1.Rodzaj = tfwKurs;


To znaczy, że dodałem wykres (funkcje) Kursu; jeżeli dodam coś takiego;

KOD cpp:     UKRYJ  
TWykres wykres1;
wykres1.Adres = 1;
wykres1.Rodzaj = tfwMul;


To znaczy, że dodałem wykres (funkcje) mnożenia;

Problemem są wyliczenia jeżeli wykres (funkcja) posiada parametry. Przykład jak to wygląda w moim edytorze. Mul(W0,100); Oznacza to, żeby wykres(funkcje) W0 pomnożyć przez 100. Mul(W0,W1); Oznacza, pomnożyć wykres(funkcje) W0 przez W1. Wszystko działa dobrze jeżeli zachowuje kolejność w edytorze, czyli piszę kolejno:

Kod: Zaznacz cały
W0 = Kurs();
W1 = Mul(W0,100);
W2 = Mul(W0,W1);


Rozpoznaje to wszystko i wektor wygląda tak: (pomijam to jak to robie pokazuje tutaj wynik końcowy)

KOD cpp:     UKRYJ  
TWykres w;
w.Adres = 0;
w.Rodzaj = tfwKurs;

Wykresy.push_back(w);

w.Adres = 1;
w.Rodzaj = tfwMul;

Wykresy.push_back(w)

w.Adres = 2;
w.Rodzaj = tfwMul;
 


Po rozpoznaniu liczę.

// PSEUDO KOD !!!!

KOD cpp:     UKRYJ  
for(int i = 0; i< Wykresy.size(); ++i) {
    TWykres w = Wykresy[i];
    // Rozpoznanie rodzaju wykresu;
    switch(w.Rodzaj) {
       case tfwKurs:
               for(poczatek danych do koniec danych); // wyliczam wartosc
       break;

       case tfwMul:
             for(poczatek danych do koniec danych); // wyliczam wartosc
       break;
    }
}



I Tutaj jest problem, który napisałem w 1 poście jeżeli napiszę tak:

Kod: Zaznacz cały
W1 = Random(255);
W2 = if(W1>100) // Jeżeli wartości z wykresu 1 są większe od 100 to wartości W2 = 1
W3 = Funkcja1(W2); // Oblicz Funkcje1 z W2


Wszytko super, jeżeli napiszę tak:

Kod: Zaznacz cały
W1 = if(W2>100);  // nie mam jeszcze wartości W2
W2 = Random(255);
W3 = Funkcja1(W2); // Oblicz Funkcje1 z W2


Mam problem bo biorę do obliczania wartości 1 wykresu, wartości 2 wykresy który obliczę dopiero po obliczeniu 1. I Chodzi mi o to, jak to rozwiązać ?? Ustalić jakiś priorytet obliczenia funkcji ?? Czyli, że wpierw muszę obliczać takie takie taki i takie funkcje a na końcu inne ???

Mam nadzieję, że lepiej to opisałem. Nie chciałem tu wklejać całego kodu bo jest go za dużo.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez Cyfrowy Baron » poniedziałek, 28 lutego 2011, 11:07

Jak dla mnie wszystko jest nazbyt niejasne, nieokreślone, niedopowiedziane, zbyt uproszczone, pominięte, etc...
Nie pomogą...
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » poniedziałek, 28 lutego 2011, 11:16

No to inaczej,

Masz wektor z 3 pozycjami; Na początek ustawiony na zero.

std::vector<int> W;

W.push_back(0);
W.push_back(0);
W.push_back(0);

i takie założenie, żeby obliczyć W[0] musisz znać W[2]; albo żeby obliczyć W[1] musisz znać W[2]

Jak najprościej określić które W muszę wpierw obliczyć. Jeżeli obliczam od początku czyli;

W[0] - potrzebuje W2 albo W1 // NIE MAM TEJ WARTOŚĆI
W[1] - Teraz dopiero ją oblicze
W[2] - Teraz dopiero ją oblicze

Czyli żeby to zadziałało muszę to liczyć w takiej kolejności.

W[2]
W[1]
W[0]

W tym przypadku jest proste bo wystarczy obliczyć od końca :-) Ale w moim tak nie jest. Dlatego pytam jak można określić które obliczenia wykonać wpierw. Jeżeli ten opis nic też nie mówi, to wywal ten post.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez polymorphism » poniedziałek, 28 lutego 2011, 11:21

Innymi słowy tworzysz prosty język skryptowy, tak?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » poniedziałek, 28 lutego 2011, 11:30

Bardziej prosty edytor w TStringGrid, w którym dodaje funkcje(wykres) postaci:

Kurs();
if(W1<100)
Mul(W1,100)
itp itd.

Funkcje wybierane są z ComboBoxa więc odrazu wiem jaka to funkcja, user tylko podaje parametry.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez polymorphism » poniedziałek, 28 lutego 2011, 11:35

No ale edytor czego? :x Co, StringGrid doda wykresy?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » poniedziałek, 28 lutego 2011, 11:43

Wrzucę screeny wieczorem.

Edytor wykresów lub jak kto woli funkcji. Dodanie wiersza w StringGridzie oznacza dodanie nowego wykresu lub funkcji. W jednej komórce wybiera się z listy funkcję i uzupełnia jej parametry. Czyli przykładowe wartość tej komórki to:
Kurs();
if(W1<100)
Mul(W1,100)
itp itd.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez polymorphism » poniedziałek, 28 lutego 2011, 12:12

Dobra, jak zwał to, tak zwał. Sprawa wydaje się prosta. W przypadku zapisu:

    W1 = if(W2>100);
    W2 = Random(255);

przy parsowaniu/obliczaniu pierwszej linii, po napotkaniu wartości W2, szukasz, czy gdzieś nie ma już obliczonej tej wartości. Jeśli jest, wiadomo. Jeśli nie ma, szukasz wyrażenia, które ją definiuje i obliczasz je. W sumie oczywista oczywistość, dość prosta w implementacji (rekurencja?).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » poniedziałek, 28 lutego 2011, 19:18

Kurde czasami na oczywiste sprawy ciężko wpaść, ja kombinowałem z priorytetami :P

Mam jeszcze pytanie, zastanawia mnie jak lepiej jest wyliczać wartości czy robić to tak: (PSEUDO KOD)


KOD cpp:     UKRYJ  
for(int w = 0;w < Wykresy.size(); ++w) {
  if(TypWykresu == 1) {
    for(int d = 0; d < Dane.size(); ++d) {
     // Obliczenie
    }
  } else if(TypWykresu ==2) {
   for(int d = 0; d < Dane.size(); ++d) {
     // Obliczenie
    }
  }
}


Czy tak:
KOD cpp:     UKRYJ  
for(int d = 0; d < Dane.size(); ++d) {
   for(int w = 0; w < Wykresy.size(); ++w) {
     if(TypWykresu==1) {
     // Obliczenia
     } else if(TypWykresu==2) {
     // Obliczenia
     }
   }
}



Ja robie sposobem numer 1, wyniki czasowe mnie zadowolają ale zastanawiam się czy można to lepiej zrobić :-)
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez polymorphism » poniedziałek, 28 lutego 2011, 21:43

Sposób #1 jest lepszy. Lepsze 10 małych pętli niż jedna duuuża i nieczytelna pętla.

p.s. zamiast konstrukcji if-else-if, użyj switch'a.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » środa, 6 kwietnia 2011, 23:22

Dobra muszę wrócić do tego tematu bo mnie to zabija cały czas.

polymorphism napisał(a):przy parsowaniu/obliczaniu pierwszej linii, po napotkaniu wartości W2, szukasz, czy gdzieś nie ma już obliczonej tej wartości. Jeśli jest, wiadomo. Jeśli nie ma, szukasz wyrażenia, które ją definiuje i obliczasz je. W sumie oczywista oczywistość, dość prosta w implementacji (rekurencja?).


No i tutaj pojawił mi się problem ... ta cała rekurencja.

Moja funkcja wygląda w skrócie tak: ( PSEUDO KOD )

Parsuje takie coś:

KOD cpp:     UKRYJ  
// W1 = if(W2>100);    // ObliczFunkcje(1);
// W2 = Random(255); // ObliczFunkcje(2);

struct TDane {
  TDateTime DataGodzina;
  std::vector<double> Wartosc;
};

struct TWykres {
    int TypWykresu;
};

std::vector<TDane> Dane;    // wektor danych zadeklarowany w pliku nagłówkowym klasy
std::vector<TWykres> Wykresy; // wektor wykresów(funkcji) zadeklarowany w pliku nagłówkowym klasy


// Typ1 założymy że jest funkcja(wykres) obliczająca IF
// Typ2 założymy że jest funkcja(wykres) wypełniająca dane liczbami losowymi.

void __fastcall ObliczFunkcje(int Adres)
{
        switch(Wykresy[Adres].TypWykresu)
        {
                case Typ1:
// Załóżmy że tutaj mi wyszło ze potrzebuje wpierw obliczenia CASE 2 i mam parametr jaki musze użyć jest to np. adres = 2
                        ObliczFunkcje(2); // kaszana jak nie wiem
                        for(int d = 0; d < Dane.size(); ++d) {
                            Dane[d].Wartosc[Adres] = // Jakieś obliczenie
                        }
                break;

                case Typ2:
                        for(int d = 0; d < Dane.size(); ++d) {
                            Dane[d].Wartosc[Adres] = Random(255);
                        }
                break;
        }
}
 

Nie mam bladego pojęcia jak to napisać - nigdy nie kumałem rekurencji :twisted:
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Re: Prośba o poradę

Nowy postprzez polymorphism » czwartek, 7 kwietnia 2011, 09:44

Ale w czym konkretnie jest problem?

(...) nigdy nie kumałem rekurencji

A co tu do kumania?! Zrozumienie, czym jest rekurencja, nie wymaga tęgiej głowy.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Prośba o poradę

Nowy postprzez Corvis » czwartek, 7 kwietnia 2011, 10:07

polymorphism napisał(a):Ale w czym konkretnie jest problem?

(...) nigdy nie kumałem rekurencji

A co tu do kumania?! Zrozumienie, czym jest rekurencja, nie wymaga tęgiej głowy.


Program wybucha i się zawiesza. Kiedyś coś baron pisał o wektorach w rekurencji i przekazywaniu ich przez referencję. Muszę znaleźć tego posta.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaChrome

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości