Prím tényezős felbontás Pascalban?
Össze kéne dobnom egy programot ami a bekért számot felbontja prím szorzatokra. Még anno sikerült a képernyőre szülnöm egy progit ami megmondja hogy prím-e és gondoltam majd abból megcsinálom ezt is. Az a gond hogy fogalmam sincs hogy hogyan vagy hogy amúgy, a program felhasználása nélkül hogyan csináljam meg.
A progi így néz ki:
program bekeres;
uses crt;
var
a,i:integer;
b: real;
o: boolean;
begin
clrscr;
writeln('Adjon meg egy szamot!');
readln(b);
a:=trunc(b);
o:=true;
for i:=2 to a div 2 do
if a mod i=0
then
o:=false;
if o=true then writeln('prim szam') else writeln('nem prim szam');
readln;
end.
2 féle képpen oldhatod meg.
1. prímekkel oszt (annak ellenére hogy elegánsabb, sokkal számításigényesebb és pazarlóbb): írsz egy ciklust, ami felbontandó számot elkezdi prímekkel osztani (ugye az elején 2vel kezd), az osztó prímeket elmenti egy tömbbe, valamint az osztott eredményt egy változóban tárolja. majd ha eljut odáig h már nem osztható tovább, írsz egy elágazást, aminél ellőrzöd h az osztott eredmény =? 1. ha igen, vége, ha nem, elleőrzi h az eredmény nagyobb e mint a legutóbbi osztó négyzete, ha igen akk az eredmény maga lesz az utolsó prímtényező; ha nem akk továbblép egy ciklusra ami prímszámokat határoz meg növekvő sorrendben. ez lényegében olyan mint a te progid, csak nem bekéri a meghatározandó számot, hanem a legutóbbi prímszámhoz kezd egy ciklusban +1et adni, amíg újra egy prímet kapsz. ezután kezdődik minden előlről, csak immáron az új prímszámmal osztva.
2. mindennel oszt (gyorsabb és egyszerűbb, és a feladat jellegéből adódóan olyan eredménye lesz mintha prímekkel lenne osztva): hasonló az 1.höz, de az új prímkeresés helyett egyszerűen az osztó értékét növeled +1el, figyelmen kívül hagyva h így nem csak prímekkel fog osztani. ugyanis hiába akar mondjuk 15el osztani, az eredmény mindig nem osztható lesz, mert már korábban 3-al és 5-el is elvégezte a felbontást. így csak a prímszámok maradnak
régen pascaloztam, de valahogy ilyesmit kell csinálnod:
szükség van a a,b,i, f egész számokra
bekéred a számot(ez lesz b)
for i:=2 to b do
for f:=1 to 2 do
if b mod i=0 then do
b:=b/i;
write(i;'*');
f:=1; (evvel azt oldjuk meg, hogy addig osszuk el
egy számmal,amíg eredményként egész számot
kapunk, vagy legalábbis azt akartam elérni)
és vége a programnak. És ha egy összetett számmal találkozik a program, azt átugorja, mivel az összes osztójával elosztottuk a számot
ezt a nagyvonalúságot annak tudható be hogy már régen pascaloztam, de remélem a lényege világos
Köszönyöm :)
Kis szintaxis hiba javítással így néz ki a program és teljesen jól működik. Még a szakkör végén én is ilyenben gondolkodtam csak a 2. for-nál felsültem.
program primtenyezo;
uses crt;
var
a,b,i,f:integer;
begin
clrscr;
writeln('Írjon be egy számot!');
readln(b);
for i:=2 to b do
begin
for f:=1 to 2 do
if b mod i=0
then
begin
b:=b div i;
write(i,'*');
end;
f:=1;
end;
repeat until keypressed;
end.
1. prímekkel oszt (annak ellenére hogy elegánsabb, sokkal számításigényesebb és pazarlóbb): írsz egy ciklust, ami felbontandó számot elkezdi prímekkel osztani (ugye az elején 2vel kezd), az osztó prímeket elmenti egy tömbbe, valamint az osztott eredményt egy változóban tárolja. majd ha eljut odáig h már nem osztható tovább, írsz egy elágazást, aminél ellőrzöd h az osztott eredmény =? 1. ha igen, vége, ha nem, elleőrzi h az eredmény nagyobb e mint a legutóbbi osztó négyzete, ha igen akk az eredmény maga lesz az utolsó prímtényező; ha nem akk továbblép egy ciklusra ami prímszámokat határoz meg növekvő sorrendben. ez lényegében olyan mint a te progid, csak nem bekéri a meghatározandó számot, hanem a legutóbbi prímszámhoz kezd egy ciklusban +1et adni, amíg újra egy prímet kapsz. ezután kezdődik minden előlről, csak immáron az új prímszámmal osztva.
"majd ha eljut odáig h már nem osztható tovább, írsz egy elágazást, aminél ellőrzöd h az osztott eredmény =? 1.ha igen, vége,"
Hogy lehet 1-nél nagyobb?
pl 35
osztható 2-vel? nem
osztható 3-al? nem
osztható 5-el? igen
35 per 5 = 7
osztható 2-vel? nem
osztható 3-al? nem
osztható 5-el? nem
osztható 7-el? igen
7 per 7 = 1
"ha nem, elleőrzi h az eredmény nagyobb e mint a legutóbbi osztó négyzete ..."
Ilyen nem lehet soha, az eddigiekből következik.
"ez lényegében olyan mint a te progid, csak nem bekéri a meghatározandó számot, hanem a legutóbbi prímszámhoz kezd egy ciklusban +1et adni, amíg újra egy prímet kapsz. ezután kezdődik minden előlről, csak immáron az új prímszámmal osztva."
Így tényleg lassabb lenne, ezt nem nevezném elegánsnak, sőtt pont ellenkezőleg.
17:31
Nagyon tévedsz, nem jó, ránézésre sem jó, gondold újra az egészet.
Egy pár példát írok amire nem jó
16 ,27, 125, 216, 1000, 10000,
Tudnék sokkal több példát is írni. A "for f:=1 to 2 do" felejtsd el, nagy butaság! Illetve csak ki kéne találni egy feladatot ahova azt használva helyes megoldást kapnánk.
18:35
szövegértelmezés, általános iskola 1. osztály
a prog lefutása 35 esetében az első (prímkeresős) módszeremmel. osztható 2? nem. 35 = 1? nem. gyök35 < 2? nem. új prím keresése. 2+1 = 3 prím? igen. 35/3? nem ... új szám 4. prím? nem. új szám 5. prím? igen! 35/5 = 7. 5 feljegyez mint prímtényező. most már 7/5 (ugye mert nem 2vel kezdjük újra, hanem ismét az utoljára használt prímmel, mint ahogy logikus és mint ahogy le is írtam!). szal 7/5? nem. 7 = 1? nem. gyök7 < 5? igen -> 7 lesz az utolsó prímtényező (remélem nem kell ecsetelnem hogy miért), 7 is elment, öröm és bódottá. remélem így már érthető.
a 2. verzió pedig sokkal gyorsabb, ugyanis egy új prímmeghatározás sokkal de sokkal több ideig tart mint egy pár felesleges nem prímes osztás (remélem ezt se kell ecsetelnem hogy miért)
"szövegértelmezés, általános iskola 1. osztály"
Akkor egy fekete pontot érdemlek. (Megnézném azt az elsőst aki ezt megérti.) Neked van igazad, ez nem az én napom (nem csak ezért), pontosabban a tegnapi mert éjfél elmúlt.
Ez a módszer lehet gyorsabb, ha a prímszámok előre ki vannak számolva, el vannak tárolva egy file-ba,(mondjuk ramdisk-en van ez a file, bár a nélkül is gyorsabb.)
Egy ilyent sikerült alkotnom de valamiért nem írja ki így azt se tudom hogy jó-e(mármint a logika).
program felbontas;
uses crt;
var
i,j,szam,maradek:integer;
oszthato,prim:boolean;
begin
clrscr;
writeln('Adjon meg egy szamot!');
readln(szam);
oszthato:=false;
i:=1;
repeat
inc(i);
repeat
prim:=true;
for j:=2 to i do
if i mod j=0
then
prim:=false; {prim ellenorzes}
if prim=true
then
if szam mod i=0
then
begin
szam:=szam mod i;
maradek:=szam;
write(i,'*');
i:=1;
oszthato:=true;
end;
until (oszthato=true) and (1<maradek);
until maradek=1;
readln;
end.
Nem jó, azért nem ír ki semmit mert végtelen ciklusba kerül, sose teljesülhet a kiírás a kilépési feltétel sem.
Akkor írok egy legegyszerűbb módszert ami felbont egy pozitív egész számot prímtényezők szorzatára.
Szerintem ez alapján csináld meg.
Ha 2-nél kisebb akkor nem lehet felbontani.
Különben 2-től haladva keresd meg a legkisebb számot ami osztja, ha ez megvan akkor (ez csak prím lehet nem kell ellenőrizned, hogy tényleg az e, nincs lehetősége nem prímnek lenni) írd ki ezt a számot és oszd le vele a felbontandó számot ismételd addig míg 1 nem lesz a felbontandó szám.
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
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!