Rysowanie histogramu

Rysowanie histogramu
VE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 10 lat
  • Postów:4
0

Cześć. Pisałem program w Borland C++ Builderze 6, którego zadaniem jest rysowanie histogramu. Fragment kodu (wykonuje się po wciśnięciu przycisku):

Kopiuj
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        double min, max, d, n;
        vector<int> p (1);
        vector<int> przedzialyp (1);
        vector<int> przedzialyk (1);
        lista.sort();
        min = lista.front();
        max = lista.back();
        lpomiarow = lista.size();
        n = floor(sqrt(lpomiarow));
        d = (max - min)/n;
        int lklas = Edit1 -> Text.ToInt();

        przedzialyp[0] = min;

        for(int i=1; i<lklas; i++)
        {
                przedzialyp[i] = przedzialyp[i-1] + d;
        }

        for(int i=0; i<lklas; i++)
        {
                przedzialyk[i] = przedzialyp[i] + d;
        }

        for (list<double>::iterator i = lista.begin(); i!= lista.end(); ++i)
        {
                for(int j = 0; j < lklas; j++)
                {
                        if((*i >= przedzialyp[j])&&(*i < przedzialyk[j]))

                         {
                               p[j]++;
                         }
                         else if ((*i==max)) p[j]++;
                }

        }


        for(int i=0;i<n;i++)
        {
                Chart1->Series[0]->Add(p[i], "", clRed);
        }
}

Wcześniej próbowałem też wersję w której liczba klas nie była pobierana od usera, ale była równa wartości zmiennej n. Niestety, przy niektórych wartościach jest dobry histogram, ale przy innych pojawia się dziwny. Co jest nie tak?

edytowany 1x, ostatnio: Vectrom
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1
Kopiuj
        int lklas = Edit1 -> Text.ToInt();
        d=(max - min)/lklas;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
VE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 10 lat
  • Postów:4
0

Obecnie kod prezentuje się tak:

Kopiuj
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        const int lklas = Edit1->Text.ToInt();
        double min, max, d, n;
        vector < int > p( lklas );
        vector < int > przedzialyp( lklas );
        vector < int > przedzialyk( lklas );
        lista.sort();
        min = lista.front();
        max = lista.back();
        lpomiarow = lista.size();
        n = floor(sqrt(lpomiarow));
        d = (max - min)/lklas;

        przedzialyp[0] = min;

        for(int i=1; i<lklas; i++)
        {
                przedzialyp[i] = przedzialyp[i-1] + d;
        }

        for(int i=0; i<lklas; i++)
        {
                przedzialyk[i] = przedzialyp[i] + d;
        }

        for (list<double>::iterator i = lista.begin(); i!= lista.end(); ++i)
        {
                for(int j = 0; j < lklas; j++)
                {
                        if((*i >= przedzialyp[j])&&(*i < przedzialyk[j]))

                         {
                               p[j]++;
                         }
                         else if ((*i==max)) p[j]++;
                }

        }


        for(int i=0;i<p.size();i++)
        {
                Chart1->Series[0]->Add(p[i], "", clRed);
        }
}

Wpisałem 7 jakiś liczb i dwie klasy - program wygenerował histogram, gdzie w 1 klasie było 7 liczb, a w drugiej 1 (łącznie 8).
Wpisałem pięć razy 1 i dwie klasy - program wygenerował histogram, gdzie były 2 klasy po 5 liczb. Co nie gra?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
2
  1. Nie używaj i++ jeżel;i możesz użyć ++i
Kopiuj
else if ((*i==max)) ++p[lklas-1];

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
VE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 10 lat
  • Postów:4
0

Wpisałem pięć razy 1 i dwie klasy - program wygenerował histogram, gdzie w jednej było 0 liczb, w drugiej 10.
Dla pięciu jakichś tam liczb i dwóch klas - w jednej z klas 4 liczby, w drugiej 2.
Aktualny kodzik:

Kopiuj
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        const int lklas = Edit1->Text.ToInt();
        double min, max, d, n;
        vector < int > p( lklas );
        vector < int > przedzialyp( lklas );
        vector < int > przedzialyk( lklas );
        lista.sort();
        min = lista.front();
        max = lista.back();
        lpomiarow = lista.size();
        n = floor(sqrt(lpomiarow));
        d = (max - min)/lklas;

        przedzialyp[0] = min;

        for(int i=1; i<lklas; ++i)
        {
                przedzialyp[i] = przedzialyp[i-1] + d;
        }

        for(int i=0; i<lklas; ++i)
        {
                przedzialyk[i] = przedzialyp[i] + d;
        }

        for (list<double>::iterator i = lista.begin(); i!= lista.end(); ++i)
        {
                for(int j = 0; j < lklas; ++j)
                {
                        if((*i >= przedzialyp[j])&&(*i < przedzialyk[j]))

                         {
                               ++p[j];
                         }
                        else if ((*i==max)) ++p[lklas-1];
                }

        }


        for(int i=0;i<p.size();++i)
        {
                Chart1->Series[0]->Add(p[i], "", clRed);
        }
} 

Dzięki za pomoc. I proszę o dalszą.

edytowany 1x, ostatnio: Vectrom
_13th_Dragon
Po kiego ci to: n = floor(sqrt(lpomiarow)); ?
VE
Pozostałości po wcześniejszej wersji - gdzie to oznaczało liczbę klas (nie było podawana przez usera).
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0
Vectrom napisał(a):

Wpisałem pięć razy 1 i dwie klasy - program wygenerował histogram, gdzie w jednej było 0 liczb, w drugiej 10.
A jakiego chcesz efektu?

Vectrom napisał(a):

Dla pięciu jakichś tam liczb i dwóch klas - w jednej z klas 4 liczby, w drugiej 2.
A tu jak ma być wg ciebie?


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
VE
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 10 lat
  • Postów:4
0

Z tymi jedynkami może być faktycznie problem, bo to te same liczby.
Ale w drugim przypadku - łącznie powinno być 5 liczb (jeśli tyle wprowadziłem). A jest 6.

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Więc sprawdź co masz w lista


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
darkbit
  • Rejestracja:ponad 20 lat
  • Ostatnio:około 17 godzin
  • Lokalizacja:~Koszalin
1
Kopiuj
vector < int > przedzialyp( lklas );
vector < int > przedzialyk( lklas ); 
//.....
for (list<double>::iterator i = lista.begin()....

Te mieszanie typów nie ma tu czasem znaczenia?

_13th_Dragon
To będzie wpływało na dokładność.
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:3 minuty
0

błąd jest tu:

Kopiuj
for (list<double>::iterator i = lista.begin(); i!= lista.end(); ++i)
        {
                for(int j = 0; j < lklas; j++)
                {
                        if((*i >= przedzialyp[j])&&(*i < przedzialyk[j]))
 
                         {
                               p[j]++;
                         }
                         else if ((*i==max)) p[j]++;
                }
 
        }

te else prowadzi do problemu.
Jak dochodzisz do wartości maksymalnej to zwiększasz wszystkie komórki!
Jak wartości maksymalna się powtarza wiele razy to robi się niezły fail.
Błąd pojawia się i znika z powodu błędu zaokrągleń przy używaniu liczb zmiennoprzecinkowych (raz wartość maksymalna ci wchodzi do ostatniego przedziału a innym razem nie i wtedy te else robi sieczkę).

Ogólnie strasznie przekombinowałeś liczenie tego histogramu.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.