Kellenne irjak egy pascal programot. De sajnos nekem meg az egyszeruek sem mennek. Hogyan valosithatom meg? (Lent)
Elkezded felbontani a számot a jegyeire és egy változóban tárolod az összegüket.
Úgy bontod fel hogy maradékosan osztasz 10-el, a maradék mindig az utolsó számjegy lesz. Ha a számon egész osztást végzel akkor meg levágja az utolsó számjegyet. A maradékokat szépen szorban összeadod és levágod.
Ezt addig csinálod amíg a 10-el való osztás eredménye 0 nem lesz (ciklus):
Ha szám 3456 akkor:
3456 mod 10 = (6)
3456 div 10 = 345
345 mod 10 = (5)
345 div 10 = 34
34 mod 10 = (4)
34 div 10 = 3
3 mod 10 = (3)
3 div 10 = 0
Ezt ciklusba helyezve pszeudokódban:
beolvas szám
összeg := 0
amíg (szám > 0):
összeg := összeg + (szám mod 10)
szám := szám div 10
kiír "A számjegyek összege: ", összeg
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
var i, szam, szam1 : integer;
begin
szam := 2468;
for i := 1 to Length(IntToStr(szam)) do szam1 := szam1 + StrToInt(IntToStr(szam)[i]);
WriteLn(szam1);
ReadLn;;
end.
#2 Neked úgy tűnik hogy vicceltem?
Miért baj ha valaki megtanul algoritmikusan gondolkozni a helyett hogy egyből a legkevésbé hatékony megoldáshoz nyúljon, ami egyébként nem rövidebb, nem sokkal egyszerűbb, viszont egy csomó átalakítást kell végezni. Maradjunk annyiban hogy többféleképpen is meg lehet oldani a problémát és én sem nézem tiéd viccnek.
Tudod én magamtól tanultam programozni és a józan paraszti logikával a számjegy karaktereit látom egy stringben. A többször egymás utáni átalakítás helyett akkor:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
var i, szam, szam1 : integer;
s_szam : string;
begin
szam := 2468;
szam1 := 0;
s_szam := IntToStr(szam);
for i := 1 to Length(s_szam) do szam1 := szam1 + Ord(s_szam[i]) - 48;
WriteLn(szam1);
ReadLn;;
end.
legyen ez, szerintem gyorsabb mint egy feltételes ciklusban lévő maradékképzés és osztás. De én nem akarok vitázni programozói végzettség nélkül.
> szerintem gyorsabb mint egy feltételes ciklusban lévő maradékképzés és osztás
Akkor szeretném hogy tisztában legyél vele, ugyan ebben az esetben nem számít, de komplexebb algoritmusok esetében hatalmas sebességromlás lehet azt elkövetni amit te tettél. Sok helyen eléggé szigorúan veszik az ilyet.
Az osztás és maradék képzés együtt a CPU-nak 1 aritmetikai művelet:
div 10
Az eax regiszterben lévő számot leosztja 10-el, a maradékot az edx-be teszi.
Most gondold át hány aritmetikai és adatmozgató műveletbe kerül 1 szöveget karakterenként átkonvertálni és eltárolni, majd kiolvasni és visszaalakítani ehhez képest. (és a memória lényegesen lassabb mint a cpu, ezért az adatmozgató művelet nagyságrendekkel lassíthatja az algoritmust)
A while ciklus csak annyiban gyorsabb a for ciklusnál hogy nem kell extra változóval végigiterálni, csak egy feltétel van benne. Megint, 1 művelet tesztelni hogy a szám pozitív e:
cmp eax,0
Ez beállítja a flageket.
Most lássuk a for feltételét: hány műveletbe kerül végigpasztázni a szövegen és megszámolni hogy milyen hosszú? Ezután megnézni hogy elértük e a végét?
<10 kizárólag aritmetikai műveletből és 1 ciklusból csináltál 200+ műveletet adatmozgatásokat és ciklusokat, és akkor nem számoltam bele hogy ezeket külső könyvtárból hívod meg és az egész könyvtárat belefordítja a compiler.
Megmondom őszintén eszembe sem jutott a számot szöveggé alakítani, hiszen általános iskolai matematikával fel tudtam bontani és elég triviálisnak tűnt a megoldás. Jó ha a kérdező olyat is lát amilyet te írtál, de nem szeretem ha viccnek tekintenek, pláne ha ez egy laikustól jön. Részemről lezárva.
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!