Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
Stránky: 1

Zdravím, mám kód (vlastní tvorba) na cyklický posun o 1, kdy se poslední znak stane prvním a ostatní se posunou o 1 dozadu. Mám ho upravdit na cyklický posun o x znaků, kde x zadá uživatel z klávesnice (zapsat dokážu). Nějak netuším, kolik znaků si musím "zapamatovat" (jinam uložit), abych je "neztratila" :(
program retez_cyklicky_posun_o_1;
uses crt;
var retez:string;
znak:char;
i:integer;
begin
clrscr;
writeln('Zadej retez: ');
read(retez);
i:=ord(retez[0]);
znak:=retez[i];
for i:=ord(retez[0]) downto 2 do retez[i]:=retez[i-1];
retez[1]:=znak;
writeln('Posunuty retez: ',retez);
end.Předem díky za nějakou radu, jak postupovat v případě posunu o x znaků.
Offline
Pokud to chceš napsat ve stejném stylu, jako máš ten posun o 1, pak si musíš zapamatovat posledních x znaků řetězce (asi do nějakého pomocného řetězce), cyklus skončit na x+1 místo 2 a uvnitř něj mít retez[i]:=retez[i-x] místo retez[i]:=retez[i-1]. Za cyklem nenaplnit pouze 1. znak řetězce, ale napsat tam celý zapamatovaný řetězec délky x postupně od prvního znaku.
Poznámka1: Je sice pravda, že v Pascalu se délka řetězce píše jako jednobytové číslo na jeho nultou pozici, takže ord(retez[0]) skutečně dává délku řetězce, ale existuje též funkce strlen(), která dělá to samé a je přehlednější v kódu.
Poznámka2: Ne že bys tohle měla hned implementovat, ale asi by ses tím docela blýskla!!! Jakýkoli posun lze realizovat jen s jednou pomocnou proměnnou, jedním zapamatovaným znakem řetězce. Idea: zapamatovat poslední znak, ten přepsat znakem, který je o x míst dopředu, pak přepsat ten znak o x míst dopředu znakem opět o x míst před ním a tak dále, dokud mi nevyjde, že mám opět přepisovat posledním znakem. To už neudělám a místo toho přepíšu znakem zapamatovaným. Říkám-li "o x míst před ním", myslím modulo strlen(retez), resp. kdykoli by index vyšel nekladný, tak přičíst strlen(retez). Počítám současně, kolik znaků jsem už přepsal. Pokud to je strlen(retez) znaků, končím, pokud ne, začínám celou proceduru znova s předposledním znakem jako počátečním. Pak předpředposledním, je-li třeba, atd. Dokonce by se dalo dopředu zjistit, kolikrát budu muset takovou proceduru spustit a kolik kroků bude uvnitř každé z nich a mohl bych si tak odpustit počítání již přepsaných znaků a test, jestli mám přepisovat počátečním znakem, ale to už je v pozadí dost vyšší matematiky, kterou dost pravděpodobně neznáš. Celá tato metoda je maximálně efektivní -- každý znak bude použit a přepsán právě jednou (což je ostatně pravda i v tvém postupu, ale takhle bys ušetřila trochu pomocných proměnných, když to řeknu trochu naivně).
Offline
↑ janca361: Není nutno pracovat s pomocným řetězcem (viz Poznámka2), ale je to pro představu a začátečníka asi vhodnější...
Offline

Mas uz to hotove? Neni to uzavrene, tak predpokladam, ze ne :-) Slo by to treba takhle:
program retez_cyklicky_posun;
uses crt;
var retez,docasny:string;
znak:char;
i,posun:integer;
begin
clrscr;
writeln('Zadej retez: ');
read(retez);
writeln('Zadej o kolik se ma posunout: ');
read(posun);
docasny:=copy(retez,ord(retez[0])+1-posun,posun);
delete(retez,ord(retez[0])+1-posun,posun);
insert(docasny,retez,1);
writeln('Posunuty retez: ',retez);
end.Anebo tak:
for i:=1 to posun do docasny[i]:=retez[ord(retez[0])+i-posun]; for i:=ord(retez[0]) downto 1+posun do retez[i]:=retez[i-posun]; for i:=1 to posun do retez[i]:=docasny[i];
U toho druheho ale nevim, jestli je korektni s retezci takhle pracovat. Je mnoho zpusobu, jak to napsat. Nevim, jestli muzete treba dynamicky alokovat pamet.
Offline

↑ Lumikodlak:
Nemám ;) Nějak se mi tím nechtělo ani zabývat, zásobu příkladů mám velkou a potřebuju udělat všechny. Zatím mám možnost si vybrat, tak si vybírám ty "hezčí" :) Když mi ↑ musixx tady: řekl, jak na to, tak mě to nějak odradilo ;)
Offline

Ok, tak predpokladam, ze se treba jeste zeptas, az na tom budes pracovat :-) (plati i pro tu druhou ulohu co tu mas)
Offline

↑ Lumikodlak:
Tak jsem se k tomu vrátila :) Druhá úloha již dokončena :)
Údělala jsem to způsobem, který mi navrhl musixx↑ zde:. Jen mám jeden problém.
program cyklicky_posun_o_x;
program retez_cyklicky_posun;
uses crt;
var retez,pomocny:string;
x:char;
i1,i2,i3:integer;
begin
clrscr;
write('Zadej retez: ');
readln(retez);
write('Zadej o kolik posunout: ');
readln(x);
i1:=1;
for i2:=(ord(retez[0])-x) to (ord(retez[0])) do begin
pomocny[i1]:=retez[i2];
i1:=i1+1;
end;
for i3:=(ord(retez[0])) downto (x+1) do retez[i3]:=retez[i3-1]
{Prirazeni pomocneho retezu (ulozenych znaku, ktere v retezu ted chybi) do retezu}
end.Jak přiřadit znaky z pomocného řetězu do přeházeného řetězu? Vím, že bude potřeba použít for-cyklus, ale nevím od kolikátého znaku je třeba začít.
Offline

(neslo mi to zkompilovat, par veci jsem tam musel upravit, ale predpokladam, ze si to opravis)
Ty znaky byly puvodne na konci, a presouvas je na zacatek, tak bych rekl, ze zacit od prvniho (anebo 'x downto 1')
Napriklad tak:
Offline
Stránky: 1