• 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

42 Warsaw Coding Academy
0 głosów
1,086 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ź 1,016 wizyt
0 głosów
2 odpowiedzi 237 wizyt
+1 głos
3 odpowiedzi 576 wizyt
pytanie zadane 3 stycznia 2016 w C i C++ przez CichoCiemny Początkujący (480 p.)

93,385 zapytań

142,384 odpowiedzi

322,540 komentarzy

62,745 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...