wiem że w Pascalu jest wbudowana funkcja zamieniająca liczbę na tablice jednowymiarową z elementami będącymi poszczególnymi cyframi tejże liczby
moje pytanie brzmi: czy móglby ktoś napisać nazwę i składnie tej funkcji?
Programuję od kilku lat w Pascalu i myślę, że o istnieniu tejże funkcji bym wiedział.
Może chodzi ci o IntToStr
/StrToInt
?
A jeżeli nie, to zauważ pewną właściwość systemu dziesiątkowego:
1234 = 1*1000+2*100+3*10+4*1
2048 = 2*1000+0*100+4*10+8*1
itd.
Wystarczy zauważyć pewną zależność i bezproblemowo sam napiszesz takową funkcję.
- Rejestracja:prawie 13 lat
- Ostatnio:prawie 13 lat
- Postów:3
Patryk27 napisał(a):
A jeżeli nie, to zauważ pewną właściwość systemu dziesiątkowego:
1234 = 1*1000+2*100+3*10+4*1
2048 = 2*1000+0*100+4*10+8*1
itd.
Wystarczy zauważyć pewną zależność i bezproblemowo sam napiszesz takową funkcję.
własnie wiem ale już miłem dość męczarni z innym div w programie i chciałem skorzystać z funkcji wbudowanej
dzięki za odpowiedź!

- Rejestracja:ponad 19 lat
- Ostatnio:2 miesiące
Jeżeli masz męczarnie z tak prostym algorytmem, to będziesz mieć męczarnie z każdym programem.
var Tb:array[0..9]of Byte;
var tmp:Byte;
var I,K,N:Integer;
var L:Cardinal;
begin
L:=1357986420;
N:=0;
repeat
Tb[N]:=L mod 10;
Inc(N); // N:=N+1;
L:=L div 10;
until L=0;
I:=0;
K:=N-1;
while I<K do
begin
tmp:=Tb[I];
Tb[I]:=Tb[K];
Tb[K]:=tmp;
Inc(I); // I:=I+1;
Dec(K); // K:=K-1;
end;
for I:=0 to N-1 do WriteLn(Tb[I]);
ReadLn;
end




- Rejestracja:prawie 13 lat
- Ostatnio:prawie 13 lat
- Postów:3
_13th_Dragon napisał(a):
Jeżeli masz męczarnie z tak prostym algorytmem, to będziesz mieć męczarnie z każdym programem.
akurat męczarnią bylo co innego
inna sprawa że wolę pisać w C++ niż w pascalu(jakoś ciężko mi idzie pascal)
no i uczę się programowania dopiero drugi rok, ale nie jest aż tak najgorzej ;)
TomRiddle napisał(a)
Funkcja IntToStr przekonwertuję liczbę na string (tablice charów).
Owszem, to wie (prawie) każdy, ale potrzeba przekonwertować liczbę na macierz cyfr, a nie znaków; Różnica jest między cyframi, a znakami (tak jak wspomniał kolega wyżej - 48
z kodu ASCII
);
Alternatywa dla macierzy dynamicznych:
program NumberSpliting;
{$APPTYPE CONSOLE}
type
TDigit = 0 .. 9;
type
TDigitsArr = array of TDigit;
procedure SplitToDigits(Value: Cardinal; var DigitsArr: TDigitsArr);
var
daTemp: TDigitsArr;
iModPart: TDigit;
I: Byte;
begin
SetLength(daTemp, 0);
repeat
iModPart := Value mod 10;
Value := Value div 10;
SetLength(daTemp, Length(daTemp) + 1);
daTemp[High(daTemp)] := iModPart;
until Value = 0;
SetLength(DigitsArr, Length(daTemp));
for I := 0 to High(daTemp) do
DigitsArr[High(DigitsArr) - I] := daTemp[I];
end;
procedure WriteDigitsAsCells(DigitsArr: TDigitsArr);
var
I: Byte;
begin
for I := 0 to High(DigitsArr) - 1 do
Write('|', DigitsArr[I]);
Write('|', DigitsArr[High(DigitsArr)], '|');
end;
var
iValue: Cardinal;
daValue: TDigitsArr;
begin
Write('Podaj liczbe [0 .. 4 294 967 295]: ');
ReadLn(iValue);
SplitToDigits(iValue, daValue);
Write('Cyfry podanej liczby: ');
WriteDigitsAsCells(daValue);
ReadLn;
end.
Cała konwersja dokonywana jest w całości w procedurze SplitToDigits
, reszta to sposób wykorzystania procedury; Wykorzystuje dodatkową macierz dynamiczną daTemp
, następnie przepisuje jej zawartość w odwrotnej kolejności do macierzy z parametru (DigitsArr
); Procedura WriteDigitsAsCells
nie jest potrzebna do konwersji, służy jedynie do ciekawszego wypisania kolejnych elementów macierzy; Działa wyśmienicie (dla typu Cardinal
oczywiście);




- Rejestracja:prawie 15 lat
- Ostatnio:około 3 godziny
- Lokalizacja:Laska, z Polski
- Postów:10056
A czemu by nie..
type
TDigit = 0 .. 9;
TDigitsArr = array of TDigit;
function IntToArray(aInt: Integer): TDigitsArr;
var I: Integer; temp: String;
begin
temp := IntToStr(aInt);
SetLength(Result, Length(temp));
for I := 0 to Length(temp) - 1 do
Result[I] := StrToInt(temp[I+1]);
end;






- Rejestracja:ponad 19 lat
- Ostatnio:2 miesiące
Ja bym zrobił to rozsądnie nie bojąc się 20% więcej kodu.
function IntToArray(Value:Cardinal):TDigitsArr;
var I,K:Integer;
var Tmp:TDigit;
begin
SetLength(Result,10);
I:=0;
repeat
Result[I]:=Value mod 10;
Value:=Value div 10;
Inc(I);
until Value=0;
SetLength(Result,I);
K:=I-1; // od tego wiersza do końca w C++ się zapisuje jako: for(int k=i-1,j=0;j<k;swap(Result[j++],Result[k--])) ;
while I<K do
begin
Tmp:=Result[I];
Result[I]:=Result[K];
Result[K]:=Tmp;
Inc(I);
Dec(K);
end;
end;

- Rejestracja:prawie 15 lat
- Ostatnio:około 3 godziny
- Lokalizacja:Laska, z Polski
- Postów:10056
Zrobiłem test. Dla mojego i Twojego sposobu wychodziły wyniki 0.0015ms, 0.0016ms, 0.0031ms, 0.0032ms mniej więcej w takim samym stosunku mniejszych do większych.





Mam jeszcze jedno rozwiązanie, trochę inne niż do tej pory wymieniliśmy; Kolejne cyfry reszty z dzielenia pakowane są od końca do macierzy, później przesuwane są po kolei o tyle miejsc, ile pól zostało nieobsłużonych licząc od początku macierzy, po czym macierz jest zmniejszana do właściwego rozmiaru:
program NumberSpliting;
{$APPTYPE CONSOLE}
type
TDigit = 0 .. 9;
type
TDigitsArr = array of TDigit;
procedure SplitToDigits(Value: Cardinal; var DigitsArr: TDigitsArr);
var
iIndex, iJump, I: Byte;
begin
SetLength(DigitsArr, 11);
iIndex := 1;
repeat
DigitsArr[11 - iIndex] := Value mod 10;
Value := Value div 10;
Inc(iIndex);
until Value = 0;
iJump := 11 - iIndex;
for I := 1 to iIndex - 1 do
DigitsArr[I - 1] := DigitsArr[I + iJump];
SetLength(DigitsArr, iIndex - 1);
end;
procedure WriteDigitsAsCells(DigitsArr: TDigitsArr);
var
I: Byte;
begin
Write('|');
for I := 0 to High(DigitsArr) do
Write(DigitsArr[I], '|');
end;
var
iValue: Cardinal;
daValue: TDigitsArr;
begin
Write('Podaj liczbe [0 .. 4 294 967 295]: ');
ReadLn(iValue);
SplitToDigits(iValue, daValue);
Write('Cyfry podanej liczby: ');
WriteDigitsAsCells(daValue);
ReadLn;
end.
@TomRiddle - jak Ci się nudzi to sprawdź szybkość w porównaniu do mojej wcześniejszej wersji :-P




- Rejestracja:ponad 19 lat
- Ostatnio:2 miesiące
function IntToArray(Value:Cardinal):TDigitsArr;
var Next:Cardinal;
var I,K:Integer;
begin
SetLength(Result,10);
I:=9;
repeat
Next:=Value div 10;
Result[I]:=Value-10*Next;
Value:=Next;
Dec(I);
until Value=0;
K:=9-I;
Move(Result[I+1],Result[0],K);
SetLength(Result,K);
end;





No i wymodziłem coś takiego:
procedure SplitToDigits(Value: Cardinal; var DigitsArr: TDigitsArr);
var
iTotal: Cardinal;
iIndex, iCount: Byte;
begin
SetLength(DigitsArr, 10);
iIndex := 9;
repeat
iTotal := Value div 10;
DigitsArr[iIndex] := Value - 10 * iTotal;
Value := iTotal;
Dec(iIndex);
until Value = 0;
iCount := 9 - iIndex;
Move(DigitsArr[iIndex + 1], DigitsArr[0], iCount);
SetLength(DigitsArr, iCount);
end;
Działa jak należy; Dzięki za wskazówki :]


