Kezdőoldal » Számítástechnika » Programozás » Hogyan lehet egy tetszőlegesen...

Hogyan lehet egy tetszőlegesen hosszú szám négyzetét kiszámolni?

Figyelt kérdés

Az összeadással és kivonással nem akadt nehézségem, a számokat stringként tárolva, majd számjegyenként, az általános iskolás írásbeli összeadás/kivonás algoritmusát felhasználva nem volt nehéz megvalósítani.

Viszont a négyzetre emelés (és a szorzás) az írásbeli szorzást leutánozva elég bonyolultnak tűnik. Nincs valami algoritmus egy szám négyzetének meghatározására?


2016. okt. 27. 10:05
1 2
 1/17 anonim ***** válasza:
15%

Egy gondolat:


A szorzás visszavezethető összeadások sorozatára...


Pl.:

5*5 = 5+5+5+5+5

2016. okt. 27. 10:13
Hasznos számodra ez a válasz?
 2/17 anonim ***** válasza:

Egyszer kellett Big Number típust csinálnom egy egyetemi beadandóhoz, akkor a szorzást egy olyan algoritmussal oldottam meg, ami hátulról előre haladva kalkulálja ki az eredmény számjegyeit.


A lényeg az volt, hogy az eredmény helyiértéke egyenlő lesz a két összeszorzott számjegy helyiértékének összegénél eggyel kisebb számmal (plusz túlcsordulás, ha túllépi a szorzat a 10-et). ÍGy meg lehetett határozni, hogy mely számjegyek szorzatai fogják meghatározni az egyes, tizes, százas, stb, helyiértéket.

Pl az eredmény első helyiértéke a két szorzandó szám első helyiértékének szorzatából fog előállni. (1+1-1=1)

Az eredmény második helyiértéke a két összeszorzandó szám első és második (1+2-1=2), valamint második és első (2+1-1=2) helyiértékének szorzatából fog előállni.

A harmadiknál nyilván az 1-3, 2-2, és 3-1 helyiértékek szorzata lesz mérvadó, és így tovább (fontos, hogy sorban haladj, mert a túlcsordulás miatt az előző helyiértékben kiszámolt szorzat is átcsúszhat a következőre).


A vicces rész ott kezdődik, amikor a két szám nem egyforma hosszú, így az egyiknek hamarabb érsz a végére, mint a másiknak. FEl kell tehát készítenia programot arra, hogy ha az egyik számból már nem tudsz magasabb helyiértékre lépni, akkor a másik számot kell magasabb helyiértéken kezdeni. (pl az egyik szám 4 jegyű, a másik 7, Az eredmény szám 5. helyiértékének meghatározásánál a 7 jegyű számnak nem fogod tudni az első helyiértékét számításba venni, mivel a másikból a 4. helyiérték a legmagasabb (4+1-1=4)


Én ezt így oldottam meg, és működött a történet.

2016. okt. 27. 11:07
Hasznos számodra ez a válasz?
 3/17 anonim ***** válasza:

egészen véletlenül még régebben csináltam egy ilyet


ahogy nézem, én úgy csináltam, egy ciklusban az 1. számot mindig a 2. szám egy adott helyiértéken lévő számával szorzom, majd a stringhez hozzáfűzök annyi nullát, amennyi a helyiértéknek megfelel.


[link]

[link]

[link]

2016. okt. 27. 11:22
Hasznos számodra ez a válasz?
 4/17 anonim ***** válasza:
az lemaradt, hogy a ciklusban a részeredményeket egy listába rakom, majd a lista tartalmát összegzem.
2016. okt. 27. 11:23
Hasznos számodra ez a válasz?
 5/17 anonim ***** válasza:
Igaz Mondó: Bár valóban igaz, amit leírtál, ha a számok olyan hosszúak, hogy nem férnek be a hagyományos típusokba, akkor azért elég sokáig tartana összeadással megoldani a dolgot. Talán érdemes egy más algoritmust keresni a probléma megoldására.
2016. okt. 27. 11:49
Hasznos számodra ez a válasz?
 6/17 coopper ***** válasza:

Szia.


Anno még Assemblerben kellet valami hasonlót összehoznom, de mivel én egyszerű ember vagyok a sima papiros szorzást programoztam le akkor, és Neked is ezt ezt javaslom.


Van a szám (ennek megvannak a számjegyei pl 100 darab számjegy).

Felveszel annyi stringet ahány számjegy van, a string hosszát kétszer akkorára veszed fel mint a számjegyek száma, ez 100 számjegy esetén 100 db 200 karakter hosszúságú stringet jelent, (ha a stringeket feltöltod valamilyen nem szám karakterrel akkor már egy kis előkészitést is végeztél).


Aztán egy ciklussal végigmész a a szorzó számjegyeket, elvégzed a számjegyek szorzását (figyelsz az átvitelekre, illetve arra is hogy a számjegynek megfelelően a string kezdetét elcsúsztatod annyi karakterrel ahányadik számjeggyel számolsz), és beleteszed a megfelelő stringbe (első számjegy az első stringben az első poziciótól kezdve, második számjegy szorzata a második stringbe a második poziciótól kezdve, stb,stb).


Ha kész utána két egymásba ágyazott ciklussal végigmész a stringeken (az egyik ciklus a stringek hosszáig(200), amíg másik ciklus a stringkek darabszámáig megy(100)), és az egymás felett lévő számokat összeadot (itt is figyelsz az átvitelre) illetve a nem szám karakterekre, egymás felett lévő számok alatt értem a string azonos poziciójában lévő számokat. Az eredményt letárolod egy stringben.


Meghatározod az eredmény string hosszát, és kiiratod.


Ha tört van a szorzásban akkor még a szabályoknak megfelelően a tizedes vessző helyét is meghatározod és belerakod az eredménybe.


Sok sikert.

üdv.

2016. okt. 27. 13:27
Hasznos számodra ez a válasz?
 7/17 anonim ***** válasza:

De amúgy ha igazán jó megoldást akarsz:

[link]

2016. okt. 27. 20:08
Hasznos számodra ez a válasz?
 8/17 SimkoL ***** válasza:

'Hátulról támadva' - értsd szorzás - Delphi-ben, kicsit bő lére eresztve:


program Project2;


{$APPTYPE CONSOLE}


uses SysUtils, Classes;


var a, b, s : String;

hossz, szorzo, szorzando, szorzat, osszeg, atvitel, hely, sor : Integer;

lista : TStringList;


begin

a := '12345678901234567890123456789012345678';

b := '32109876543210987654321012345678901234';

lista := TStringList.Create;

hossz := Length(a) + Length(b) + 3;

sor := 0;

for szorzo := Length(b) downto 1 do

begin

atvitel := 0;

hely := 0;

s := StringOfChar('0', hossz);

for szorzando := Length(a) downto 1 do

begin

szorzat := (Ord(a[szorzando]) - 48) * (Ord(b[szorzo]) - 48) + atvitel;

atvitel := szorzat div 10;

s[hossz - hely - sor] := Chr((szorzat mod 10) + 48);

Inc(hely);

end;

s[hossz - hely - sor] := Chr(atvitel + 48);

Inc(sor);

WriteLn(s);

lista.Add(s);

end;

s := StringOfChar('-', hossz);

WriteLn(s);

s := StringOfChar('0', hossz);

atvitel := 0;

for hely := hossz downto 1 do

begin

osszeg := 0;

for sor := 0 to lista.Count - 1 do osszeg := osszeg + (Ord(lista.Strings[sor][hely]) - 48);

osszeg := osszeg + atvitel;

atvitel := osszeg div 10;

s[hely] := Chr((osszeg mod 10) + 48);

end;

WriteLn(s);

while s[1] = '0' do Delete(s, 1, 1);

WriteLn(#10#13, 'Az "tiszta" eredmény: ',#10#13, s);

lista.Free;

ReadLn;

end.

2016. okt. 27. 21:38
Hasznos számodra ez a válasz?
 9/17 SimkoL ***** válasza:
Kép: [link]
2016. okt. 27. 21:42
Hasznos számodra ez a válasz?
 10/17 coopper ***** válasza:

Szia.


Volt egy kis időm, így én is leprogramoztam ezt a feladatot, menet közben átgondoltam a logikát és nem kell a string tömb, kb. két string elég az egészhez.


Az elmélet : Egy ciklusban szorzod az első számot a második szám megfelelő számjegyével. Aztán ezt a részeredményt összeadod az eredmény stringjével (Ez két függvény : SzorzasEgyJeggyel és Osszead).


A konzolról kéri be a számot (de csak egy ellenőrzés van benne: a tizedes vesszőt kicseréli tizedes pontra, ha van benne tizedes vessző)


Aztán kiírja az egyes részeredmények értékét. Majd a végeredményt is.


Kezeli a törteket is (legalább is kiszedi a tizedespontot a beadott adatokból és meghatározza a végeredmény tizedesjegyeinek számát, és alkalmazza is a végeredményen).


Itt a forrás (Delphi konzolos alkalmazás) : [link]


Itt a lefordított exe : [link]


Itt a virustotal ellenőrzése: 11/56 ami elég sok ahhoz képest, hogy szinte semmi olyan kódod nem irtam bele ami ezt a magas "virusos" arányt okozhatja : [link]


Sok sikert.

üdv.

2016. okt. 28. 15:33
Hasznos számodra ez a válasz?
1 2

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!