funkcja zamieniajaca liczbe na tablice jedno wymiarowa

0

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?

0

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ę.

0
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ź!

1

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
0
_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 ;)

0

Funkcja IntToStr przekonwertuję liczbę na string (tablice charów).

0
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);

0

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;
0

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;
0

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.

0

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

0
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;
0

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 :]

1 użytkowników online, w tym zalogowanych: 0, gości: 1