Stránka 1 z 1
Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 18:39
od amd.21
Zdravím,
mám za úkol napsat převodník z 10-kové soustavy do 4,9,20-kové soustavy, převod je jednoduchý to chápu, prostě vypisuju ( rovnou tisknu na obrazovku ) zbytky po celočíselném dělení. Takto se ale výsledné číslo vypíše pozpátku. V programování jsem docela začátečník, a tak nevím, jak jednoduše číslo vypsat pozpátku. Mohli byste mi s tím někdo pomoct ?
Díky moc.
Re: Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 19:37
od beardie
ukladaj do pola a pole vypis od konca
Re: Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 22:05
od amd.21
To mě taky napadlo, ale jak deklaruju bezrozměrné pole ? Nebo spíš pole, které se bude zvětšovat podle toho, kolik čísel bude ?
Re: Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 22:20
od Maranov
Ale ty víš, jak velké to pole musí být.

Podle velikosti toho datového typu, ve kterém je uloženo vstupní číslo.
Dejme tomu, že je to 32bit. int - maximální hodnota je 2 147 483 647, např. v oktalové soustavě je to 7FFFFFFF, takže potřebuješ 8 číslic v poli (plus znaménko). Víc nikdy nebudeš potřebovat.
Re: Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 22:59
od amd.21
Takže pro 4-kovou už to +- mám :
Kód: Vybrat vše
#include <iostream>
using namespace std;
int main()
{
int n, pom;
int pole4[10];
cout << "Zadej cislo v desitkove soustave : ";
cin >> n;
for(int x = 0; x<10; x++)
{
pom = n%4;
pole4[x] = pom;
if(n>3)
{
n = n/4;
}
else
{
n = 0;
}
}
for(int y = 9; y>=0; y--)
{
cout << "Cislo ve ctyrkove soustave : " << pole4[y];
}
return 0;
}
Ještě bych měl pár otázek pokud můžu:
1) Jak se zbavím přebytečných nul na začátku čísla ?
2) Převod pro 9-kovou soustavu zvládnu , to je to stejné, akorát dělím jiným číslem,ale pro 20-kovou soustavu mám použít čísla 0-9 a písmena a-j. Nevím, jak pak (elegantně) nahradit čísla 11-20 písmeny a-j.
Díky za vaši ochotu.
Re: Výpis čísel pozpátku C++
Napsal: stř 5. říj 2011, 23:44
od bubanek
Takhle to vypadá v pascalu:
Kód: Vybrat vše
i := 0;
while (cislo <> 0) do begin
a[i] := cislo mod zaklad;
cislo := cislo div zaklad;
i := i+1;
end;
Pro až 20 soustavu si udělej pole znaků oindexované 0 až 20 a ulož do něj pro odpovídající číslo odpovídající znak. For example:
0 -> 0
5 -> 5
10 -> A
15 -> F
etc
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 06:14
od amd.21
Jo asi už vím, proč to dělat jednoduše, kdyř to jde i složitě

(Počítám, že <> je "nerovná se", správně ?)
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 09:50
od bubanek
jo
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 09:56
od Maranov
amd.21 píše:Kód: Vybrat vše
if(n>3)
{
n = n/4;
}
else
{
n = 0;
}
Zbytečné, po vydělení 4mi beztak zůstane v n nula, taky počet cyklů by šel zoptimalizovat pro menší čísla - viz bubanek.
amd.21 píše:Kód: Vybrat vše
for(int y = 9; y>=0; y--)
{
cout << "Cislo ve ctyrkove soustave : " << pole4[y];
}
return 0;
}
Není to blbě? 10x vypisuješ "Cislo ve ctyrkove soustave : ".
amd.21 píše:1) Jak se zbavím přebytečných nul na začátku čísla ?
2) Převod pro 9-kovou soustavu zvládnu , to je to stejné, akorát dělím jiným číslem,ale pro 20-kovou soustavu mám použít čísla 0-9 a písmena a-j. Nevím, jak pak (elegantně) nahradit čísla 11-20 písmeny a-j.
Díky za vaši ochotu.
1) Prostě ve for místo pole4[y] dej podmínku, třeba (pole4[y] != 0 ? pole4[y] : "").
2) Já bych to dělal takhle: int je jako prvek pole celkem zbytečný, i char by měl velkou rezervu, bude to mít i výhodu toho, že to budou přímo písmena k tisku, takže změnil bych typ pole. Nejdříve bych si poukládal do pole obyčejné čísla 0-19, jak to máš doteď. Následně bych pak převáděl (přímo při tisku, nebo čistěji úpravou pole předem a pak tiskem):
pokud je prvek 0-9 - přičti ASCII hodnotu '0' - což je 48
pokud je prvek 10-19 - přičti ASCII hodnotu 'A' -což je 65
Z pole čísel ti tak vznikne pole čísel překódovaných na znaky, stačí pak vytisknout.
amd.21 píše:Jo asi už vím, proč to dělat jednoduše, kdyř to jde i složitě

(Počítám, že <> je "nerovná se", správně ?)
Ano.
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 17:30
od amd.21
Maranov píše:Není to blbě? 10x vypisuješ "Cislo ve ctyrkove soustave : ".
Ano.
Jo toho jsem si hned vzápětí všimnul. Programuju teprve chvíli a ještě nemám vychytané tyhle "dětské" chyby.
Ještě úplně nechápu
Následně bych pak převáděl (přímo při tisku, nebo čistěji úpravou pole předem a pak tiskem):
pokud je prvek 0-9 - přičti ASCII hodnotu '0' - což je 48
pokud je prvek 10-19 - přičti ASCII hodnotu 'A' -což je 65
Můžeš mě, prosím, trošku nakopnout ? Nechci hotové řešení, jen postup jak to +- udělat.
Jinak jsem trošku poupravil kód, snad je to lepší.
Kód: Vybrat vše
#include <iostream>
using namespace std;
void MujPrevod(int n);
int main()
{
int n, pom;
cout << "Zadej cislo v desitkove soustave : ";
cin >> n;
MujPrevod(n);
return 0;
}
void MujPrevod(int n)
{
int pole[10] = {0};
int i = 0;
while (n != 0)
{
pole[i] = n%4;
n = n/4 ;
i++;
}
cout << "Cislo ve ctyrkove soustave : ";
for(i=i-1; (i)>=0; i--)
{
cout << pole[i];
}
cout << endl;
}
Prosím váš názor, díky.
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 17:48
od Maranov
'pom' je nevyužitá, určitě ti to háže i Warning. Jinak nic víc mne nenapadá, víc už ti fakt můžu napsat jen hotové řešení, prostě to uprav, jak píšu. Změň typ pole na char[10] a po převedení jinou soustavu všechny hodnoty ještě uprav, jak jsem psal.
Vychází to z principu, jak jsou znaky uložené:
https://secure.wikimedia.org/wikipedia/en/wiki/Ascii
C/C++ je jazyk, který je trochu blíž netypovému přístupu, jak funguje v CPU samotném, takže se znakem se dá zacházet jak s číslem (jeho ASCII hodnota), tak jako s tím, co reprezentuje (při výpisu).
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 18:24
od apoc9
amd.21 píše:To mě taky napadlo, ale jak deklaruju bezrozměrné pole ? Nebo spíš pole, které se bude zvětšovat podle toho, kolik čísel bude ?
Co třeba nějaký linked list?
http://www.algoritmy.net/article/24/Spojovy-seznam
Nejsem C++ programátor, ale očekával bych, že C++ bude mít nějakou implementaci už hotovou. Pak stačí projít všechny prvky v pořadí jakém potřebuješ.
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 20:53
od amd.21
Tak jo, díky moc, hlavně "Maranovovi" za pomoc, myslím že to mám. Každopádně to funguje, jedině pokud byste měli nějaké výhrady k programu jako takovému( že jde třeba něco udělat jednodušeji) tak mi ještě prosím řekněte. Díky
Kód: Vybrat vše
#include <iostream>
using namespace std;
void Prevod(int n, int m);
int main()
{
int n;
cout << "Zadej cislo v desitkove soustave : ";
cin >> n;
Prevod(n,4);
Prevod(n,9);
Prevod(n,20);
return 0;
}
void Prevod(int n, int m)
{
char pole[10] = {0};
int i = 0;
while (n != 0)
{
pole[i] = n%m;
if(pole[i]>=0 && pole[i]<=9)
{
pole[i] += 48;
}
else
{
pole[i] += 55;
}
n = n/m ;
i++;
}
cout << "Cislo v " << m << " soustave : ";
for(i=i-1; (i)>=0; i--)
{
cout << pole[i];
}
cout << endl;
}
Re: Výpis čísel pozpátku C++
Napsal: čtv 6. říj 2011, 23:27
od Maranov
Nó, výhrady by byly... jestli teda můžu:
(jsem kritický člověk)
Čistě z hlediska znovupoužitelnosti kódu - není dobré vypisovat výstup funkce na cout, lepší je vracet řetězec, ale jako učební příklad to stačí.
Záporná čísla jsou problém - buď implementuj podporu i pro ně nebo nastav vstupní podmínky tak, že číslo má být kladné. Jinak signatura funkce vypadá, že bere jakékoliv číslo. Stačilo by změnit int na unsigned int (možná bude kompilátoru vadit nějaké operace mezi různými typy, ale to vyřešíš explicitní konverzí).
Další problém je velikost m - není ošetřená a velikost pole se podle něj neřídí. S dostatečně malým m a velkým n dojde k přístupu mimo pole. Co se týče ohlašování chyb v jazyce C, většinou se používá int jako návratový typ, jako je tomu u main. Pokud je vše OK, vrátíš 0, pokud ne, vrátíš třeba -1.
Nejsem si jistý, zda char pole[10] = {0}; skutečně vynuluje všechny prvky pole, pokud se nepletu, tak jen první. Pozor ať nevypisuješ blbosti, které tam zůstanou neinicializované.
Podm. pole
>=0 mi přijde celkem zbytečná, pokud pracuješ jen s kladnými čísly.
for(i=i-1; (i)>=0; i--) je celkem kostrbatý zápis. Zamysli se, jak zde ušetřit jednu operaci. 
Není zač. 
Re: Výpis čísel pozpátku C++
Napsal: pát 7. říj 2011, 06:35
od amd.21
Maranov píše:Nó, výhrady by byly... jestli teda můžu:
(jsem kritický člověk)

Čistě z hlediska znovupoužitelnosti kódu - není dobré vypisovat výstup funkce na cout, lepší je vracet řetězec, ale jako učební příklad to stačí.
No jasně, to ale nevím jak se dělá (zatím)
Maranov píše:
Záporná čísla jsou problém - buď implementuj podporu i pro ně nebo nastav vstupní podmínky tak, že číslo má být kladné. Jinak signatura funkce vypadá, že bere jakékoliv číslo. Stačilo by změnit int na unsigned int (možná bude kompilátoru vadit nějaké operace mezi různými typy, ale to vyřešíš explicitní konverzí).
OK, dopíšu tam vstupní podmínku.
Maranov píše:
Další problém je velikost m - není ošetřená a velikost pole se podle něj neřídí. S dostatečně malým m a velkým n dojde k přístupu mimo pole. Co se týče ohlašování chyb v jazyce C, většinou se používá int jako návratový typ, jako je tomu u main. Pokud je vše OK, vrátíš 0, pokud ne, vrátíš třeba -1.
takže, velikost m asi není potřeba zadávat ne ? na m se totiž neptám, jen abych nemusel psát funkci 3x, tak jsem ho přímo dal do parametru volání funkce. No a ohlašování chyb, to je podle mě už trochu mimo mé momentální znalosti. Vím, že by se to tak mělo dělat, ale ještě to budu muset pořádně prostudovat
Maranov píše:
Nejsem si jistý, zda char pole[10] = {0}; skutečně vynuluje všechny prvky pole, pokud se nepletu, tak jen první. Pozor ať nevypisuješ blbosti, které tam zůstanou neinicializované.
Jo, díval jsem se do debuggeru, celé pole je 0.
Maranov píše:
Podm. pole
>=0 mi přijde celkem zbytečná, pokud pracuješ jen s kladnými čísly.
for(i=i-1; (i)>=0; i--) je celkem kostrbatý zápis. Zamysli se, jak zde ušetřit jednu operaci.
if(pole<=9) a tak ? 
for(i -= 1; i>=0; i--) tak ? 
Re: Výpis čísel pozpátku C++
Napsal: pát 7. říj 2011, 13:10
od Maranov
amd.21 píše:1) takže, velikost m asi není potřeba zadávat ne ? na m se totiž neptám, jen abych nemusel psát funkci 3x, tak jsem ho přímo dal do parametru volání funkce. No a ohlašování chyb, to je podle mě už trochu mimo mé momentální znalosti. Vím, že by se to tak mělo dělat, ale ještě to budu muset pořádně prostudovat

2) Jo, díval jsem se do debuggeru, celé pole je 0.
3a) if(pole
<=9) a tak ? 
3b) for(i -= 1; i>=0; i--) tak ? 
1) Nepsat kód třikrát je taky velice dobře. Jen musíš mít promyšlené to, jak m ovlivňuje velikost toho pole - buď ho odvozovat z m nebo přidat vstupní podmínku, že m musí být v daném intervalu. Technicky vzato, tak jak to máš může být i záporné... výsledky by asi pak nebyly dobré. 
Jinými slovy, každá funkce musí mít přesně definované rozhraní a žádná z dovolených hodnot by neměla způsobit chybu.
2) Máš pravdu, nastaví to první prvek na 0 a ostatní vynuluje. Funguje to ale jen s nulou, u ostatních hodnot to nastaví jen první a ostatní vynuluje.
3a) Ano.
3b) Třeba. Musím přestat psát v noci, nevím co jsem měl na mysli tou jednou operací, ale takhle to vypadá líp. 
Re: Výpis čísel pozpátku C++
Napsal: pát 7. říj 2011, 14:52
od amd.21
Kód: Vybrat vše
#include <iostream>
using namespace std;
void Prevod(int n, short int m); // prototyp funkce Prevod
int main()
{
int n; // deklarace promenne n
do // zacatek cyklu do-while
{
cout << "Zadej nezaporne cislo v desitkove soustave, 0 pro ukonceni programu : "; // vyzva k zadani cisla pro prevod
cin >> n; // nacteni cisla do n
if(n>0) // n musi byt vetsi nez 0
{
Prevod(n,4); // volani funkce Prevod pro 4kovou soustavu
Prevod(n,9); // volani funkce Prevod pro 9kovou soustavu
Prevod(n,20); // volani funkce Prevod pro 20kovou soustavu
}
else if(n<0) // pokud uzivatel zada n zaporne
cout << "Cislo musi byt kladne !\n"; // vypiseme chybovou hlasku
} while(n!=0); // konec cyklu do-while, cyklus bezi, dokud se n nerovna 0
return 0;
} // konec funkce main
void Prevod(int n, short int m) // definice funkce Prevod
{
char pole[10] = {0}; // pole typu char o 10 promennych, všechny proměnné vynulovány
int i = 0; // pomocna promenna i, ktera pocita pocet probehnuti cyklu
while (n != 0) // cyklus while bezi, dokud ze zadaneho cisla n "nezbude" 0
{
pole[i] = n%m; // nacteni zbytku po celociselnem deleni na pozici i v poli "pole"
if(pole[i]<=9) // pokud je hodnota v poli mensi nez 9 vcetne
{
pole[i] += 48; // k hodnote pricitame 48, jelikoz jde o typ pole char, pracujeme tedy se znaky ASCII tabulky (znak s cislem 48 odpovida 0)
}
else // pokud neni hodnota v poli mezi 0 az 9 vcetne
{
pole[i] += 55; // pricteme 55, stejne jako vyse pracujeme s ASCII tabulkou,(znaku A odpovida cislo 65, ale nase zbytky po deleni zacinaji na 10, tzn 65-10 = 55)
}
n = n/m ; // vydeleni n/m beze zbytku
i++; // i zvetsujeme o 1 pri kazdem prubehu cyklu, i nam nasledne urcuje, klik znaku vypiseme z pole
} // konec while
cout << "Cislo v " << m << " soustave : ";
for(i-=1; (i)>=0; i--) // cyklus vypisuje hodnoty z pole pozpatku, jen tolikrat kolikrat probehl cyklus while vyse
{
cout << pole[i]; // vypis hodnot z pole
}
cout << endl;// novy radek
} // konec funkce Prevod
tak snad finální verze, včetně komentářů
Re: Výpis čísel pozpátku C++
Napsal: pát 7. říj 2011, 15:36
od Maranov
Celkem fajn.
Re: Výpis čísel pozpátku C++
Napsal: pát 7. říj 2011, 15:41
od amd.21
Tak jo, díky za konzultaci a pomoc, jdu to odeslat
