C# - Jak udělat aritmetický průměr Vyřešeno

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Uživatelský avatar
belier
Level 1
Level 1
Příspěvky: 98
Registrován: únor 11
Bydliště: R.p.R
Pohlaví: Muž
Stav:
Offline
Kontakt:

C# - Jak udělat aritmetický průměr

Příspěvekod belier » 11 bře 2011 21:12

Zdravím, učím se z knihy C# pro zelenáče a vymyslel jsem si příklad ke zrealizování a to sice program na výpočet aritmetického průměru z počtu hodnot zadaných uživatelem (pro znalce to bude zřejmě brnkačka, ale já se na tom snažím něco naučit).
Mám zatím tohle:
List<int> hodnoty = new List<int>();
Console.WriteLine("Zadejte počet hodnot: ");
int počet = int.Parse(Console.ReadLine());
Console.WriteLine("Zadejte hodnoty: ");

for (int i=0;i<počet;i++)
{
int čísla = int.Parse(Console.ReadLine());
hodnoty.Add(čísla);
}
Hodnoty uložím do seznamu, ale nevím, jak je ze seznamu vytáhnout a sečíst mezi sebou. Potom už zbývá zřejmě jen ten součet uložit do proměnné a podělit počtem zadaných hodnot. Jediné co se mi podařilo, bylo hodnoty ze seznamu vypsat.
Napadl mě cyklus for (int n=0; n<počet;n++) ale nevím, jak sečíst ty hodnoty.
Díky
Naposledy upravil(a) Žbeky dne 11 bře 2011 21:17, celkem upraveno 1 x.
Důvod: Upřesněn nadpis

Reklama
Uživatelský avatar
Žbeky
Moderátor
Guru Level 13
Guru Level 13
Příspěvky: 22288
Registrován: květen 08
Bydliště: Vsetín - Pardubice
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod Žbeky » 11 bře 2011 21:19

Udělej to jednoduše přes pole

Console.WriteLine("Zadejte počet hodnot: ");
int počet = int.Parse(Console.ReadLine());
int[] pole = new int[počet];
Console.WriteLine("Zadejte hodnoty: ");

for (int i=0;i<počet;i++)
{
pole[i] = int.Parse(Console.ReadLine());
}


S tím, že nakonec sečteš všechny prvky pole a vydělíš proměnnou "počet"
V SZ řeším jen záležitosti týkající se fóra. Na prosby a žádosti o technickou podporu nereaguji. Díky za pochopení.

HiJackThis + návod - HW Monitor - Jak označit příspěvek za vyřešený - Pravidla fóra

Uživatelský avatar
Suril
Level 3
Level 3
Příspěvky: 406
Registrován: únor 09
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod Suril » 12 bře 2011 00:20

A ještě drobná poznámka - nepoužívej v názvech proměnných a funkcí diakritiku (viz. proměnná čísla). Některým kompilátorům by to nemuselo dělat dobře a stejně tak pokud bys někdy něco velkého dělal, tak tomu nikdo nebude rozumět (v zahraničí) a když se to učíš, je vždycky lepší naučit se to tak, aby to bylo použitelné ;) Chápeš doufám, jak to myslím :)
I believe in winners and loosers and in freedom to fail

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod faraon » 12 bře 2011 07:30

belier píše:Napadl mě cyklus for (int n=0; n<počet;n++) ale nevím, jak sečíst ty hodnoty.

Takovým cyklem jsi ten seznam hodnot vypsal? Tak tam místo výpisu hodnoty dej její přičtení k celkovému součtu, ale nezapomeň ho před začátkem vynulovat!

Nevím jak v C#, ale v C ti int/int vyjde zase int, takže 7/2 = 3 a ne 3,5! Mohl bys třeba ty zadané hodnoty ukládat jako float, budeš tak moci zpracovávat i desetinná čísla ;-)
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)

Uživatelský avatar
belier
Level 1
Level 1
Příspěvky: 98
Registrován: únor 11
Bydliště: R.p.R
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C# - Jak udělat aritmetický průměr

Příspěvekod belier » 12 bře 2011 14:04

Díky, ten první program už jsem dodělal, změnil jsem typy na double, aby počítal s desetinnými čísly a i tu diakritiku u proměnných jsem opravil. Teď ale zkouším ten program udělat tak, aby uživatel zadával hodnoty a při zadání '0' se čtení ukončilo a proběhl výpočet AP.
Zatím mám tohle:
class AP2
{
static bool Checknula(double pole);

static void Main(string[] args)
{
Console.WriteLine("Zadejte hodnoty pro výpočet aritmetického průměru a ukončete '0' ");

bool nula = false;
while (!nula)
{
int i = 0;
double[] pole = new double[int.Parse(Console.ReadLine())];
i++;
//checknula
}
double soucet = 0;
for (int i = 0; i < pole.Length; i++)
{
soucet += pole[i];
}
Console.WriteLine("Aritmetický průměr zadaných hodnot je: {0}", soucet / pole.Length);
Console.ReadLine();
}
}

Jenže nevím, jak dopsat metodu Checknula, aby zkontrolovala zadanou hodnotu v cyklu a v případě 0 vrátila hodnotu true a tím pádem ukončila čtení. A dále ješte musím nějak vyřešit to, že mi kompilátor háže chybu u sčítání prvků pole, protože to pole neexistuje.
Díky za jakékoliv nasměrování.

Uživatelský avatar
Suril
Level 3
Level 3
Příspěvky: 406
Registrován: únor 09
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod Suril » 12 bře 2011 15:04

no tak pokud nechceš, aby se ti ta nula počítala do průměru, tak ten test musíš provést ještě před samotným zápisem do pole, čili si musíš vytvořit nějakou proměnnou. tzn:

Kód: Vybrat vše

int i =0;
while (!nula)
{
  double temp = Console.ReadLine() /*nedělám C#, dělám C++, správná syntaxe může být možná jiná-zkrátka uložení vstupu z klávesnice*/
  if(checknula(temp))  //zavolá funkci checknula a pošle jí hodnotu temp
  {
    break;   //pokud checknula vrátí true, smyčka while se přeruší
  }
  pole[i] = temp; //pokud se dojde až sem, uloží se uživatelem zadaná hodnota do pole a zvýší se používaný index
  i++;
}

všimni si, že int i = 0 musí být před smyčkou, tak, jak jsi to měl, tedy v ní, se vždycky inicializovala na hodnotu nula a tys neustále přepisoval hodnotu pole[0].

Samotná funkce checknula může vypadat takto:

Kód: Vybrat vše

bool checknula(double cislo)
{
  if(cislo)   //pokud cislo neni rovno nule, podmínka je splněna a vrací se false
    {
       return false;
    }
  return true;  //pokud není splněna předchozí podmínka, znamená to, že číslo je nulové a vrací se true
}


Doufám, že jsem správně pochopil tvůj problém a pomůže ti to. Určitě se ještě ptej, kdybys nevěděl.

Pozn. Umím C++, syntaxe C# je podobná a taky jsem se s ní setkal, ale je trošku jiná, takže možné jsou banální syntaktické chyby, které určitě najdeš a opravíš, ale samotná logika a struktura by měla být správná
I believe in winners and loosers and in freedom to fail

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod faraon » 12 bře 2011 17:03

Nešlo by to takhle nějak?

Kód: Vybrat vše

bool nula = false;
double temp;
int i = 0;
while (temp=int.Parse(Console.ReadLine()))
{
     double[] pole = new double[temp];
     i++;
}

Akorát jestli to dobře chápu, tak int.Parse ti načte hodnotu int, nemělo by tam být double.Parse? Schválně tomu zkus zadat do vstupu nějakou desetinou hodnotu, jestli jí to přičte nebo ořízne.

Je tu jeden háček, pokud nezadáš žádnou hodnotu, tak ti to spadne na dělení nulou, takže to musíš ohlídat:

Kód: Vybrat vše

if (pole.Length)
    Console.WriteLine("Aritmetický průměr zadaných hodnot je: {0}", soucet / pole.Length);
else
    Console.WriteLine("Nebyla zadána žádná hodnota!");
Console.ReadLine();


Suril: to jsi na tom pořád o trochu lépe než já, máš tam aspoň ty třídy, metody, objekty... I když C# vychází víc z Javy než z C++ :-D
V čistém Céčku bych to řešil všechno v jedné smyčce:

Kód: Vybrat vše

#define MAX 1000

int main(void)
{
    double soucet=0,pole[MAX];
    int pocet;

    for(pocet=0;pocet<MAX;++pocet)
    {
        scanf("%lf",&pole[pocet]);
        if(pole[pocet]==0) break;
        soucet+=pole[pocet];
    }

    if(pocet)
        printf("Aritmetický průměr zadaných hodnot je: %f\n",soucet/pocet);
    else
        printf("Nebyla zadána žádná hodnota!\n");

    return 0;
}

Cyklus for probíhá dokud se nedosáhne maximální velikost pole, pokud se dřív zadá 0, tak z něj ten break vyskočí, a neprovede se přičtení k celkovému součtu ani ++pocet. Akorát že pár věcí je v C++ "jinak", tak doufám že ten break tam nechali :blush:
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)

Uživatelský avatar
belier
Level 1
Level 1
Příspěvky: 98
Registrován: únor 11
Bydliště: R.p.R
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C# - Jak udělat aritmetický průměr

Příspěvekod belier » 12 bře 2011 18:02

Suril: díky, ale řekl bych, že tam máš chybu, protože hodnoty načítáš do "temp", ale v Checknula pracuješ s "cislo". Jinak mám ještě malý problém, který jsem nedořešil a to sice syntaxi zapsání zadané hodnoty do pole. Tak, jak to je teď to hodí error, že je index mimo pole.

static bool Checknula(double cislo)
{
if (cislo != 0)
{
return false;
}
return true;
}
static void Main(string[] args)
{
Console.WriteLine("Zadejte hodnoty pro výpočet aritmetického průměru a ukončete '0'");
double soucet = 0;
bool nula = false;
int i = 0;
double[] pole = new double[i];
while (!nula)
{
double cislo = double.Parse(Console.ReadLine());
if (Checknula(cislo))
{
break;
}
pole[i] = cislo;
i++;
}
for (int n = 0; i < pole.Length; n++)
{
soucet += pole[i];
}
Console.WriteLine("Aritmetický průměr zadaných hodnot je: {0}", soucet / pole.Length);
Console.ReadLine();

--- Doplnění předchozího příspěvku (12 Bře 2011 18:06) ---

faraon: teď to mám jinak, předtím jsem načítal hodnoty přímo do pole, jinak v zásadě to mám stejně jako ty, ale ani ty tam nemáš vyřešeno to uložení zadané hodnoty do pole, pokud se nemýlím.

Uživatelský avatar
Suril
Level 3
Level 3
Příspěvky: 406
Registrován: únor 09
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod Suril » 12 bře 2011 18:35

belier píše:díky, ale řekl bych, že tam máš chybu, protože hodnoty načítáš do "temp", ale v Checknula pracuješ s "cislo"

kdepak, je to zcela regulérní postup. Při volání funkce jí pošlu hodnotu, nikoli proměnnou samotnou. Ta proměnná má platnost pouze ve funkci, ve které byla deklarována. Posíláš tedy jen hodnotu, kterou si potom volaná funkce přiřadí do proměnné, kterou si vytvoří v sobě. A ta se může jmenovat úplně stejně a klidně i úplně jinak. Je pravda, že ve většině případů je pro přehlednost kódu lepší používat stejné názvy, v tomhle případě mi přišlo vhodnější použít názvy jiné, protože název temp ve volané funkci... prostě mi to přišlo divné :-D

a teď k tvé chybě. Řekl bych, že chyba je v těchto řádcích:

Kód: Vybrat vše

int i = 0;
double[] pole = new double[i];


nejdřív vytvoříš proměnnou o hodnotě 0 a pak vytvoříš pole s rozměry této proměnné - tedy 0. Kompilátor si tedy nevyhradí žádné místo pro pole, protože mu řekneš, že má nulovou velikost.
Pokud chceš vytvořit pole, měl bys nejdřív vědět, jak bude velké. Nejdřív by tedy měl uživatel vložit velikost pole - tzn. kolik chce zadávat čísel.
Čili nějak takhle (opět omluv mé nedostatky C# syntaxe):

Kód: Vybrat vše

Console.WriteLine("Vložte počet čísel, z nichž se bude počítat aritmetický průměr");
int x = Console.ReadLine();
double[] pole = new double[x];


čili teď budeš mít pole o x prvcích, přičemž x budeš znát. Pak vlastně i odpadá problém s ukončením pomocí nuly (pokud to tedy vyloženě mermomocí nechceš) a celé řešení bude velmi banální:

Kód: Vybrat vše

Console.WriteLine("Vložte počet čísel, z nichž se bude počítat aritmetický průměr");
int x = Console.ReadLine();
double[] pole = new double[x];
double soucet = 0;
for (int i = 0; i < x; i++)
{
  Console.WriteLine("Vložte ",i,". číslo");
  pole[i] = Console.ReadLine();
  soucet += pole[i];
}
Console.WriteLine("Aritmetický průměr čísel je ", soucet/pole.length());


Tohle by měl být v podstatě celý kód ( plus ještě nezbytnosti jazyka C#, které, jak říkám, nemám v malíku). Mohlo by to tak fungovat, zkus a dej vědět
I believe in winners and loosers and in freedom to fail

Uživatelský avatar
belier
Level 1
Level 1
Příspěvky: 98
Registrován: únor 11
Bydliště: R.p.R
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C# - Jak udělat aritmetický průměr

Příspěvekod belier » 12 bře 2011 18:59

Jasně, takhle jak navrhuješ jsem to tady řešil poprvé a jak už jsem i výše psal, tímto způsobem jsem to zdárně dokončil. Já jsem právě chtěl zkusit udělat tak, že neznám počet hodnot a uživatel bude psát jen hodnoty. Je to sice zbytečně složitější, než ta původní verze, ale mě šlo o procvičení práce s poli. Jinak máš pravdu, je to tím, že pole má velikost 0, ale teď nevím, zda se dá nějak vytvořit pole u kterého neznáme předem velikost.

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C# - Jak udělat aritmetický průměr

Příspěvekod CZechBoY » 12 bře 2011 21:03

co si zažádat uživatele aby to oddělil třeba čárkama? pak hodíš jen split a vše přečteš, rozdělíš do pole, uděláš průměr
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: C# - Jak udělat aritmetický průměr

Příspěvekod faraon » 12 bře 2011 21:10

belier píše:faraon: teď to mám jinak, předtím jsem načítal hodnoty přímo do pole, jinak v zásadě to mám stejně jako ty, ale ani ty tam nemáš vyřešeno to uložení zadané hodnoty do pole, pokud se nemýlím.


Vypadá to že jsem špatně pochopil tohle:
double[] pole = new double[int.Parse(Console.ReadLine())];
Připadalo mi z toho tvého kódu že to uvnitř cyklu zvětší pole o jednu položku a do ní zapíše načtenou hodnotu :roll:
Takže pro upřesnění - tím new se vytvoří pole o zadaném počtu položek? Pokud ano, máš dvě možnosti:

1) udělat dostatečně velké pole, tak jak jsem to definoval tím MAX 1000 v tom mém céčkovém programu, ze kterého použiješ jen část, není pravděpodobné že by někdo ručně zadával do konzole víc než 1000 položek 8), ale také není problém si je tam poslat ze souboru: program.exe<data.txt, takže si to musíš ohlídat.

2) najít si jak se mění velikost alokované paměti za běhu programu, v Céčku jsou na to funkce malloc(velikost) - alokuje požadovaný objem paměti, a realloc(pole, velikost) - alokuje novou požadovanou velikost a do toho místa překopíruje obsah starého pole. A nezapomeň jí na konci programu zase uvolnit! Zagooglil jsem a vypadlo na mě tohle:
Array.Resize(ref a, a.GetUpperBound(0) + 1);

V Céčku by to vypadalo takhle:

Kód: Vybrat vše

int main(void)
{
    double soucet=0,temp;
    double *pole=NULL;
    int pocet=0;

    pole=malloc(0);

    for(pocet=0;;++pocet)
    {
        scanf("%lf",&temp);
        if(temp==0)
            break;
        else
            pole=realloc(pole,sizeof(double)*(pocet+1));
        pole[pocet]=temp;
        soucet+=temp;
    }

    if(pocet)
        printf("Aritmetický průměr zadaných hodnot je: %f\n",soucet/pocet);
    else
        printf("Nebyla zadána žádná hodnota!\n");

    free(pole);
    return 0;
}

To pole=malloc(0); tam ani být nemusí, realloc() si ho při prvním použití vytvoří. Má to ale jednu velkou nevýhodu, každé volání systému žere dost výkonu, takže ten program bude citelně pomalejší než se statickým polem. Taková malá daň z luxusu ;-)

P.S. To je v C# normální, míchat deklarace a kód programu? Z tohohle mě jímá hrůza (a to jsem začínal s BASICem):
Console.WriteLine("Vložte počet čísel, z nichž se bude počítat aritmetický průměr");
int x = Console.ReadLine();
double[] pole = new double[x];
double soucet = 0;
for (int i = 0; i < x; i++)...
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)


  • Mohlo by vás zajímat
    Odpovědi
    Zobrazení
    Poslední příspěvek

Zpět na “Programování a tvorba webu”

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 6 hostů