• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Program znajdujący liczbę najbliższą średniej

Object Storage Arubacloud
0 głosów
618 wizyt
pytanie zadane 27 października 2018 w C i C++ przez Hinzeq Użytkownik (860 p.)

Cześć,

Wiem, że podobne tematy zostały już utworzone (czytałem je), ale mój problem jest inny.

Napisałem program który wczytuje X liczb typu float z klawiatury (chcę by był uniwersalny), następnie liczy średnią i podaje liczbę najbliższą średniej.

Kod:

#include <iostream>

using namespace std;

float czy_poprawnie(float x){
    bool stan_x;
    do{
        cin.clear();
        cin.ignore();
        cin>>x;
        stan_x=cin.good();
        if(stan_x==0)cout<<"Wprowadzono niepoprawne dane. Podaj ponownie: ";
    }while(stan_x==0);
    return x;
}

int main()
{
    cout<<"Ile liczb w tablicy(najpierw ENTER): ";
    int ile=czy_poprawnie(0);
    float liczba[ile],srednia,suma=0,szukana1=1,szukana2=2,x1,x2,y;
    for(int i=0;i<ile;i++){
        cout<<"Podaj "<<i+1<<" liczbe: ";
        liczba[i]=czy_poprawnie(0);
        suma=suma+liczba[i];
    }
    cout<<endl<<"\tSuma: "<<suma<<endl;
    srednia=suma/ile;
    cout<<"\tSrednia: "<<srednia<<endl;


    for(int i=0;i<ile;i++){         
        for(int j=0;j<ile;j++){
            if(liczba[i]<srednia&&liczba[i]>liczba[j]) // PROBLEM 
                szukana1=liczba[i];
        }
    }
    cout<<"Szuk1: "<<szukana1<<endl; // dla sprawdzenia

    for(int i=0;i<ile;i++){
        for(int j=0;j<ile;j++){
            if(liczba[i]>srednia&&liczba[i]<liczba[j]) // PROBLEM 
                szukana2=liczba[i];
        }
    }
    cout<<"Szuk2: "<<szukana2<<endl; // dla sprawdzenia

    x1=srednia-szukana1;
    x2=szukana2-srednia;
    cout<<"x1: "<<x1<<endl; // dla sprawdzenia
    cout<<"x2: "<<x2<<endl; // dla sprawdzenia

    y=x1-x2;
    if(y<0)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana1<<endl;
    else if(y>0)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana2<<endl;
    else if(x1==x2)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana1<<endl;

    return 0;
}

Niestety raz działa, raz nie. Co jest głupim podejściem (chcę mieć kontrolę nad programem).
Najprawdopodobniej coś w warunku jest nie ta (zaznaczyłem w kodzie), niestety nie mam pojęcia jak to obejść.

Bardzo prosił bym o pomoc.

Pozdrawiam,
Hinzeq

3 odpowiedzi

0 głosów
odpowiedź 27 października 2018 przez RafalS VIP (122,820 p.)

Strasznie to przekombinowane. Możesz skorzystać z funkcji abs i liczyć odleglosc liczby od sredniej jako abs(liczba - srednia).

Co do kodu to nazwa funkcji czy_poprawnie jest myląca. Jak programista widzi nazwe zaczynającą się na czy lub is to spodziewa się, że ta zmienna / funkcja odpowiada na pytanie czy, na które są dwie odpowiedzi tak lub nie - czyli jest typu bool. 

int ile=czy_poprawnie(0);
float liczba[ile];

to nie powinno się skompilować, ale najwidoczniej korzystasz z kompilatora który przymyka oko na łamanie standardu.

A ja bym to napisał tak:

int main()
{
	cout << "Ile liczb w tablicy(najpierw ENTER): ";
	int ile = wczytuj_liczbe_do_skutku();
	vector<double> liczby(ile);
	for (size_t i = 0; i < ile; i++) {
		cout << "Podaj " << i + 1 << " liczbe: ";
		liczby[i] = wczytuj_liczbe_do_skutku();
	}
	double srednia = std::accumulate(liczby.begin(),liczby.end(),0.0) / ile;
	cout << *max_element(liczby.begin(), liczby.end(), [srednia](double a, double b) {
		return abs(a - srednia) > abs(b - srednia);
	});
	return 0;
}

 

0 głosów
odpowiedź 27 października 2018 przez chucksqll Stary wyjadacz (12,930 p.)
  cout<<"Ile liczb w tablicy(najpierw ENTER): ";
    int ile=czy_poprawnie(0);
    float liczba[ile]

Taka deklaracja tablicy nie jest poprawna, nieważne czy u Ciebie działa czy nie. Nazywa się to VLA, poniżej link dlaczego tak nie powinno się robić:

https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard

Poprawną wersją jest

int ile=...
float *liczba=new float[ile];

Albo możesz użyć jakiegoś kontenera.

Co do samych warunków to ciężko mi je zrozumieć, są łatwiejsze sposoby na znalezienie liczby najbliższej średniej, np. użycie funkcji abs() zwracającej wartość bezwzgledną z wyrażenia, przykład poniżej.

if(abs(liczba[i]-srednia) < abs(liczba[i]+1 -srednia))
{
     liczbaNajblizszaSredniej=liczba[i];
}

 

0 głosów
odpowiedź 28 października 2018 przez Hinzeq Użytkownik (860 p.)

Faktycznie.. wskaźniki..

Dodałem trochę warunków i działa teraz poprawnie:


#include <iostream>

using namespace std;

float wczytaj_liczbe_do_skutku(float x){
    bool stan_x;
    do{
        cin.clear();
        cin.ignore();
        cin>>x;
        stan_x=cin.good();
        if(stan_x==0)cout<<"Wprowadzono niepoprawne dane. Podaj ponownie: ";
    }while(stan_x==0);
    return x;
}

int main()
{
    cout<<"Ile liczb w tablicy(najpierw ENTER): ";
    int ile=wczytaj_liczbe_do_skutku(0);
    float *liczba=new float [ile];

    float srednia,suma=0,szukana1=1,szukana2=2,x1,x2,y;
    for(int i=0;i<ile;i++){
        cout<<"Podaj "<<i+1<<" liczbe: ";
        liczba[i]=wczytaj_liczbe_do_skutku(0);
        suma=suma+liczba[i];
    }
    cout<<endl<<"\tSuma: "<<suma<<endl;
    srednia=suma/ile;
    cout<<"\tSrednia: "<<srednia<<endl;


    for(int i=0;i<ile;i++){
        for(int j=0;j<ile;j++){
            if(liczba[i]<=srednia&&liczba[i]>liczba[j])
                szukana1=liczba[i];
        }
    }
    //cout<<"Szuk1: "<<szukana1<<endl; // dla sprawdzenia

    for(int i=0;i<ile;i++){
        for(int j=0;j<ile;j++){
            if(liczba[i]>=srednia&&liczba[i]<liczba[j])
                szukana2=liczba[i];
        }
    }
    //cout<<"Szuk2: "<<szukana2<<endl; // dla sprawdzenia

    x1=srednia-szukana1;
    x2=szukana2-srednia;
    //cout<<"x1: "<<x1<<endl; // dla sprawdzenia
    //cout<<"x2: "<<x2<<endl; // dla sprawdzenia

    y=x1-x2;
    if(y<0)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana1<<endl;
    else if(y>0)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana2<<endl;
    else if(x1==x2&&szukana1!=szukana2)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana1<<" i "<<szukana2<<endl;
    else if(x1==x2)
        cout<<"\tLiczba najblizej sredniej to: "<<szukana1<<endl;


    delete [] liczba;

    return 0;
}

Dziękuję za odpowiedzi, teraz zapoznam się z "vector" i "abs" i spróbuję w ten sposób.

Pozdrawiam,
Hinzeq :)

Podobne pytania

0 głosów
1 odpowiedź 515 wizyt
0 głosów
2 odpowiedzi 131 wizyt
+1 głos
3 odpowiedzi 464 wizyt
pytanie zadane 3 stycznia 2016 w C i C++ przez CichoCiemny Początkujący (480 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...