06. december 2004 - 08:57 Der er 18 kommentarer og
2 løsninger

Tælle med en alphanumerisk værdi

Findes der i Delphi, en indbygget rutine der kan tælle en alphanumerisk værdi?
F.eks. Hvis man har en værdi 'a85411', så skal de næste jo hedde 'a85412', 'a85413', 'a85414' og så videre.
Eller man har en værdi '7541-1', så skal de næste jo hedde '7541-2', '7541-3'...'7541-9', '7541-10' og så videre.
Ok '-' er ikke en alphanumerisk værdi. :-)
Eller 'fq00098', så skal de næste jo hedde 'fq00099', 'fq00100' og så videre.
Den første del af værdien er 'ikke numerisk', og den sidste del af værdien er 'numerisk'.
Den 'ikke numeriske' del kan godt være ikke eksisterende, dvs. at der godt kan forekomme rene numeriske værdier. Den numeriske del kan indeholde foranstillede nuller, og de skal blive der. Det skal være den samme rutine der står for at tælle.
Værdien er gemt i en streng.
Avatar billede arne_v Ekspert
06. december 2004 - 09:25 #1
Jeg er lidt bange for at du bliver nødt til selv at skrive noget for noget
så specielt.
Avatar billede lavang Nybegynder
06. december 2004 - 22:51 #2
Hvad skal det bruges til?
Avatar billede delphi Nybegynder
06. december 2004 - 23:24 #3
Prøv det her som jeg lige har skruet sammen til dig. Jeg testede lidt og som jeg forstår opgaven, så virker det.

Procedure AlphaAdd(Const InpStr : String; Var OutStr : String);
Var
  ilen : Integer;
  idx  : Integer;
Begin
  OutStr := '';
  iLen  := Length(InpStr);
  If iLen=0 Then Exit;

  For idx := iLen DownTo 1 Do
    If (InpStr[idx]<'0') Or (InpStr[idx]>'9') Then
      Break;

  If (InpStr[idx]<'0') Or (InpStr[idx]>'9') Then
    Begin
      OutStr := Copy(InpStr, 0, idx) +
                IntToStr(StrToInt(Copy(InpStr, idx+1, iLen))+1)
    End
  Else
    OutStr := IntToStr(StrToInt(InpStr) + 1);
End;
06. december 2004 - 23:47 #4
Det firma hvor jeg arbejder, har vi en mængde stumper der er serienummereret efter producentens forgodtbefindende, alle formater, som jeg har set indtil nu, slutter med en numerisk del. Det skal bruges til at registrere hvor de forskellige dele er købt, og i hvilke produkter de indgår i, i produktionen. Langt de fleste producenter nummererer dem fortløbende. Så for at gøre det nemt at indtaste dem ville det være smart med en routine der selv kunne tælle op.

Jeg sad i går aftes og biksede denne rutine sammen.

function TForm3.Naeste(V: String):String;
var
  A: String;  // Eventuel ikke-numerisk første del af nummeret.
  N: String;  // Heltals tæller i slutningen af nummeret.
  P: Integer;  // Position hvor alphanumerisk og numerisk skiller.
  L: Integer;  // Antal cifre i den numeriske del, mht. foranstillede nuller.
begin
  P := Length(V);
  while (P > 0) and (V[P]>='0') and (V[P]<='9') do
    P := P - 1;
  A := Copy(V, 1, P);            // A = Den alphanumeriske del.
  N := Copy(V, P+1, Length(V));  // N = Den numeriske del.
  if N = '' then N := '0';        // Der skal være en numerisk del.
  L := Length(N);
  N := IntToStr(StrToInt(N) +1);  // Tæl en frem.
  while Length(N) < L do          // Hvis der er foranstillede nuller på den
    N := '0' + N;                // numeriske del, skal disse bibeholdes,
  Naeste := A + N;                // indtil værdien kræver et ciffer mere.
end;

Hvis der er en der kan lave den kortere/simplere end dette er der point.
Avatar billede tolderlund Nybegynder
07. december 2004 - 13:38 #5
Den her er da kortere :-)

function Naeste(V: String):String;
var
  P: Integer;  // Position hvor alphanumerisk og numerisk skiller.
begin
  P := Length(V);
  while (P > 0) and (V[P] in ['0'..'9']) do
    P := P - 1;
  Result := Copy(V, 1, P) + IntToStr(StrToIntDef(Copy(V, P+1, Length(V)), 0)+1);
  while Length(Result) < Length(V) do
    Insert('0', Result, P+1);
end;
Avatar billede tolderlund Nybegynder
08. december 2004 - 11:04 #6
Lidt kortere igen :-)

function Naeste(V: String):String;
var
  P: Integer;  // Position hvor alphanumerisk og numerisk skiller.
begin
  P := Length(V);
  while (P > 0) and (V[P] in ['0'..'9']) do
    P := P - 1;
  Result := Copy(V, 1, P) + Format('%.'+IntToStr(Length(V)-P)+'d', [StrToIntDef(Copy(V, P+1, Length(V)), 0)+1]);
end;
Avatar billede delphi Nybegynder
08. december 2004 - 23:01 #7
Galning! ;)  Det er squ da umugeligt at yde service på det kode!  Prøv at gennemskue den slags fx. om bare tre måneder.
Avatar billede tolderlund Nybegynder
09. december 2004 - 09:33 #8
Sådan er kort kode jo typisk.
Avatar billede delphi Nybegynder
09. december 2004 - 19:29 #9
"Umugeligt" - hvad hulen er det for noget bavl at skrive.... stik mig flux en staveplade!
09. december 2004 - 22:31 #10
Der er lige før Delphi havde fået point. Den sidste kommentar fik mig til at grine så meget at jeg næt havde spildt alt min kaffe ned i tastaturet.
Tolderlund: Har du en ide om hvilken en af de viste eksempler der er hurtigst.
Avatar billede tolderlund Nybegynder
10. december 2004 - 15:56 #11
Hm, godt spørgsmål, jeg tester lige ...
Helt uvidenskabeligt:
Jeg kørte begge rutiner igennem 1000000 (1 million) gange.
Med input 'Test1'
Rutine 1: 2094 ms (millisekunder)
Rutine 2: 3187 ms
Med input 'Test0098'
Rutine 1: 2797 ms
Rutine 2: 3265 ms
Konklusion: den første rutine er vist hurtigst.
Avatar billede delphi Nybegynder
10. december 2004 - 16:30 #12
Jeg ser altså 4 forslag.....
Avatar billede tolderlund Nybegynder
10. december 2004 - 22:20 #13
Du skal da også brokke dig :-)
Jeg testede kun mine egne rutiner.
Men i øvrigt, din rutine fungerer ikke helt.
Ved input af 'Test0098' giver den 'Test99' og ikke som krævet 'Test0099'.
Ved input af '0098' giver den '99' og ikke som krævet '0099'.
Og ved input af f.eks. 'Test' giver den en Exception error, men input af kun alfanumerisk er dog ikke dækket af opgavebeskrivelsen.
Avatar billede arne_v Ekspert
11. december 2004 - 00:47 #14
Prøv:

function incr4(s : string) : string;

var
  add,i : integer;
  res : string;

begin
  res := s;
  add := 1;
  i := length(res);
  while add > 0 do begin
    res[i] := chr(ord(res[i]) + add);
    if res[i] > '9' then begin
      res[i] := chr(ord(res[i]) - 10);
      add := 1;
    end else begin
      add := 0;
    end;
    i := i - 1;
  end;
  incr4 := res;
end;
Avatar billede tolderlund Nybegynder
11. december 2004 - 10:19 #15
Beklager arne, men med 'Test9' som input giver din rutine en fejl.
Avatar billede arne_v Ekspert
11. december 2004 - 10:49 #16
Hvis den skal kunne øge længde af strengen, så skal den modificeres til:

function incr4(s : string) : string;

var
  add,i : integer;
  res : string;

begin
  res := s;
  add := 1;
  i := length(res);
  while add > 0 do begin
    if (res[i] < '0') or (res[i] > '9') then begin
      res := copy(res, 1, i) + '0' + copy(res, i + 1, length(res) - i);
      i := i + 1;
    end;
    res[i] := chr(ord(res[i]) + add);
    if res[i] > '9' then begin
      res[i] := chr(ord(res[i]) - 10);
      add := 1;
    end else begin
      add := 0;
    end;
    i := i - 1;
  end;
  incr4 := res;
end;
11. december 2004 - 15:42 #17
Hej Tolderlund.
Du har gjort et fint stykke arbejde, du får pointene.
Avatar billede tolderlund Nybegynder
11. december 2004 - 18:24 #18
Takker.
Avatar billede arne_v Ekspert
11. december 2004 - 20:37 #19
Fik du testet hastighed med incr4 ?
Avatar billede arne_v Ekspert
18. december 2004 - 20:57 #20
06/12-2004 23:47:17
07/12-2004 13:38:14
08/12-2004 11:04:38
11/12-2004 10:49:02

giver hos mig:

Test1
Test2 1281
Test2 1094
Test2 1813
Test2 312
Test0098
Test0099 1625
Test0099 1563
Test0099 1859
Test0099 328
Test0199
Test0200 1422
Test0200 1391
Test0200 1843
Test0200 360
Test9
Test10 1344
Test10 1109
Test10 1828
Test10 1047

eller på dansk:
  - hvis strengen ikke skal gøres længere så er mit forslag ca. 3-5 gange hurtigere
  - hvis strengen skal gøres længere så er mit forslag ca. lige så hurtigt
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Capgemini Danmark A/S

AI Data Architect

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger to sektionschefer til Systemafdelingen i Hvidovre

Politiets Efterretningstjeneste

API-udvikler til PET

JP/Politikens Hus

Klient Tekniker