Rysowanie histogramu

Rysowanie histogramu
VE
  • Rejestracja: dni
  • Ostatnio: dni
  • 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?

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
1
Kopiuj
        int lklas = Edit1 -> Text.ToInt();
        d=(max - min)/lklas;
VE
  • Rejestracja: dni
  • Ostatnio: dni
  • 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: dni
  • Ostatnio: dni
2
  1. Nie używaj i++ jeżel;i możesz użyć ++i
Kopiuj
else if ((*i==max)) ++p[lklas-1];
VE
  • Rejestracja: dni
  • Ostatnio: dni
  • 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ą.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
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?

VE
  • Rejestracja: dni
  • Ostatnio: dni
  • 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: dni
  • Ostatnio: dni
0

Więc sprawdź co masz w lista

darkbit
  • Rejestracja: dni
  • Ostatnio: dni
  • 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?

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
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.

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.