Rysowanie histogramu

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):

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?

1
        int lklas = Edit1 -> Text.ToInt();
        d=(max - min)/lklas;
0

Obecnie kod prezentuje się tak:

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?

2
  1. Nie używaj i++ jeżel;i możesz użyć ++i
else if ((*i==max)) ++p[lklas-1];
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:

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ą.

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?

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.

0

Więc sprawdź co masz w lista

1
vector < int > przedzialyp( lklas );
vector < int > przedzialyk( lklas ); 
//.....
for (list<double>::iterator i = lista.begin()....

Te mieszanie typów nie ma tu czasem znaczenia?

0

błąd jest tu:

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1