funkcja zamieniajaca liczbe na tablice jedno wymiarowa

2012-05-21 17:19

Rejestracja: 7 lat temu

Ostatnio: 7 lat temu

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?

Pozostało 580 znaków

2012-05-21 18:32
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Wrocław

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


Pozostało 580 znaków

2012-05-21 22:38

Rejestracja: 7 lat temu

Ostatnio: 7 lat temu

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

Pozostało 580 znaków

2012-05-21 22:58

Rejestracja: 14 lat temu

Ostatnio: 3 minuty temu

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

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Pokaż pozostałe 8 komentarzy
A tego twego podejścia nie kumam, raz wolisz mieć char i byte a raz char i char? I to w zależności C czy C++? Coś nie domawiasz. - _13th_Dragon 2012-05-23 20:14
C++ jest dla mnie bardziej wysokopoziomowy i wolałbym, żeby kompilator zgłaszał mi błąd przy probie niejawnej konwersji char (znak) <--> char (liczba - tutaj mogla by byc inna nazwa typu np.: byte). w C wole tak jak jest bo uzywam C prawie jak assemblera czyli do typowo niskopoziomowych operacji - krwq 2012-05-23 20:22
Właściwie to wole by mi kompilator nie bruździł przy tym: char x='7'; int y=x-'0'; Ale gdyby mogłem składać życzenia to wolałbym mieć dwa różne char: char - automagicznie niekonwertowalny do int oraz dodatkowy np ichar - automagicznie konwertowalny na int. Wtedy wszystko byłoby idealnie. - _13th_Dragon 2012-05-23 20:34
@_13th_Dragon: o jakie brużdżenie chodzi? ten kod działa pod C, pod C++ i pod C# nawet. - Azarien 2012-05-23 21:39
@Azarien, zgadza się - na całe szczęście. Chodzi mi o brużdżenie standardu C++KQ, wg pomysłu od @krwq opisanemu kilka komentarzy wyżej. Nie przerażaj się - nie opisał całego standardu ;P - _13th_Dragon 2012-05-23 21:44

Pozostało 580 znaków

2012-05-22 19:53

Rejestracja: 7 lat temu

Ostatnio: 7 lat temu

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

Pozostało 580 znaków

2012-05-23 13:00

Rejestracja: 9 lat temu

Ostatnio: 2 godziny temu

0

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


Pozostało 580 znaków

2012-05-23 14:08
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 4 minuty temu

Lokalizacja: Tuchó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);


edytowany 1x, ostatnio: furious programming, 2012-05-23 14:11
Zwiększanie rozmiaru tablicy na każdym kroku - stanowczo odradzam, o wiele lepiej zadeklaruj od razu na 10 znaków więcej w Cardinal nie będzie, a po zakończeniu konwersji, jeden raz zmniejsz do właściwego rozmiaru. Nie rozumiem poco używasz tymczasowej tablicy skoro możesz użyć docelowej. Zmień trochę kolejność wewnątrz repeat ... unil i odpadnie potrzeba w zmiennej iModPart. Generalnie to nie pojmuję po kiego każdy krok próbujesz skomplikować, np czemu nie można: Write('|'); for I:=0 to High(DigitsArr) do Write(DigitsArr[I],'|'); mniej kodu oraz o jedno odejmowanie mniej - _13th_Dragon 2012-05-23 15:36
Zaczyna mi się podobać Twoje poprawianie moich kodów :) Cardinal owszem, więcej jak 10 znaków nie przyjmie, jedno odejmowanie to nie strata czasu; Jeśli o macierz chodzi - wolałem mieć tyle elementów, co znaków; Nie rozumiem dlaczego piszesz, że "wszystko próbuję komplikować" - po prostu Ty znasz trochę szybsze rozwiązanie; Choćbym nie wiem co napisał to i tak zawsze znajdzie sie ktoś, kto poprawi kod na szybszy; Ten algorytm nie musi być ultra szybki, ale dzięki za wskazówki; Mnie cieszy każdy napisany kod pod warunkiem, że działa; Optymalizacja to już inna sprawa :P - furious programming 2012-05-23 17:06
Aha, jeśli chodzi o tymczasową macierz - Ty przesuwasz elementy w docelowej, ja przepisuję ją z tymczasowej do docelowej w odwrotnej kolejności; Wiadome, Twój kod jest szybszy, mój trzeba zoptymalizować; Gdybym usiadł i zastanowił się to znalazłbym sposób na przyspieszenie go; Jeszcze mi daleko to super efektywnych kodów, ale dzięki za wskazówki; - furious programming 2012-05-23 17:09

Pozostało 580 znaków

2012-05-23 15:57

Rejestracja: 9 lat temu

Ostatnio: 2 godziny temu

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;

Pokaż pozostałe 3 komentarze
Nie wszystko co jest wizualnie krótsze jest takim w rzeczywistości. - _13th_Dragon 2012-05-23 16:26
Wątpię żeby ułamek milisekundy zrobił pytającemu różnicę. - TomRiddle 2012-05-23 16:28
Ale jaja zwraca twoja krótsza wersja, przy wywołaniu IntToArray(-1); - _13th_Dragon 2012-05-23 16:37
a jak czajnik „niema” pokrywy? - Azarien 2012-05-23 21:47
To: 1. Zrób pokrywę; 2. Włóż na czajnik; 3. Wywołaj pierwszy algorytm; 4. Wywal pokrywę; 5. Koniec algorytmu. I niech mnie diabli jeżeli nie jest to krótszy zapis od kopii pierwszego algorytmu po wywaleniu punktów 2 i 4. ;) Niestety właśnie tak rozumuje większość programistów. :/ - _13th_Dragon 2012-05-23 21:53

Pozostało 580 znaków

2012-05-23 16:38

Rejestracja: 14 lat temu

Ostatnio: 3 minuty temu

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;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 4x, ostatnio: _13th_Dragon, 2012-05-23 16:43

Pozostało 580 znaków

2012-05-23 16:53

Rejestracja: 9 lat temu

Ostatnio: 2 godziny temu

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.


Fajnie że zrobiłeś, tylko że tak to przedstawiłeś że nie kumam co ci wyszło. - _13th_Dragon 2012-05-23 18:12
Dla każdej z metod zrobiłem test 10 razy, w którym powtarzałem metodę 10000 razy a wynik podzieliłem przez 10000. Wyszedł średni czas w milisekundach. W tych 10 razach, powtarzały się ww czasy. - TomRiddle 2012-05-23 19:31
Nie pytałem o metodologie, zaś o czasy masz 4 podanych wartości, algorytmów dwa. - _13th_Dragon 2012-05-23 19:47
Wyników było w sumie 20 (10 testów na algorytm) ale się powtarzały, więc zapisałem takie jakie były. - TomRiddle 2012-05-23 20:40
No tak 5 dzieleń ekstra i opłaca się utworzenie napisu z char'a. A wstaw tam do tej swojej sprawdzarki to co zaraz dokleję na koniec tematu. - _13th_Dragon 2012-05-23 20:54

Pozostało 580 znaków

2012-05-23 18:03
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 4 minuty temu

Lokalizacja: Tuchów

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


Jak już chcesz optymalizować to proszę. Pomysł sensowny, tylko że realizacja ... 1. SetLength(DigitsArr,10); 11 - niema takiej opcji; 2. zacznij od iIndex := 9; a w pętle rób Dec(iIndex); oszczędzisz średnio 5 odejmowań; 3. Zamiast kopiować bajt po bajtu użyj Move(); 4. div + mod = dwa dzielenia da się zrobić na jednym: Next:=Value div 10; DigitsArr[iIndex]:=Value-10*Next; Value:=Next; niby więcej operacji a jest szybciej. - _13th_Dragon 2012-05-23 18:21
Ty to potrafisz zmotywować człowieka... Nie mogę ustawić SetLength(DigitsArr, 10), bo pętla przesuwająca spowoduje błędy; Dlatego jest na 11, trzeba by ją zmienić; W sumie to odejmowanie daje w dupę, można przecierz tak jak piszesz dekrementować "iIndex" i też będzie; Spróbuję z Move(), tylko czy kopiowanie tak jak jest będzie wolniejsze od tej procedury? Skoro tak piszesz, to pewnie tak; - furious programming 2012-05-23 20:52
Obejrzyj post niżej ;P - _13th_Dragon 2012-05-23 20:56

Pozostało 580 znaków

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