Avatar billede azs Nybegynder
12. august 2003 - 21:07 Der er 18 kommentarer og
3 løsninger

Finde 0'er i en string

Hvordan kan jeg finde de første 0'er der er før i en random string som kan se sådan her ud 012/0013/00001/0053 osv.

Hvis der er nogle 0'er før det første tal fra 1..9 i den string, finde ud af hvor mange 0'er der er, så jeg kan bruge det til en Case som denne

case Nul of
0:NyStr := '0'
00:NyStr := '00'
000:NyStr := '000'
0000:NyStr := '0000'
end;

Håber der er nogen som ved hva jeg mener og kan hjælpe mig ;)
Avatar billede abpdk Nybegynder
12. august 2003 - 21:15 #1
Jeg er ikke helt med på hvad det er du vil?
Avatar billede azs Nybegynder
12. august 2003 - 21:19 #2
fx. jeg har et tal (random men som en string fordi brugeren selv kan taste det ind). Det tal kan se sådan her ud 38/012/0013/00001/0053 osv.

Så er det at jeg har brug for at vide hvor mange 0'er der er forand selve det tal hvis der er nogen. Men hvordan kan jeg det ? og hvordan kan jeg vide hvor mange der er af 0'er hvis der er noget ?
Avatar billede abpdk Nybegynder
12. august 2003 - 21:22 #3
Du kalder "38/012/0013/00001/0053" for ét tal. Vil du bare vide hvor mange nuller der er foran hele den streng, eller foran de enkelte tal (her delt med '/')?...Og i så fald, kan man regne med at strengen altid er formateret sådan?
Avatar billede azs Nybegynder
12. august 2003 - 21:46 #4
ja.. det er kun eksempler der er så det er et nyt tal efter '/' og de kan ik skrive andet end tal så det vil blive et eller andet tal.
Avatar billede abpdk Nybegynder
12. august 2003 - 22:08 #5
Denne funktion (som sikkert kan laves smartere, når jeg er mere vågen :)), finder antallet af nuller foran en given streng:

function NumLeadZero(str: String): integer;
var
  i: integer;
begin
  result:=0;
  for i:=0 to length(str) do
    if (Ord(str[i+1]) <> 48) then begin
      result:=i;
      exit;
    end;
end;

Hvis du vil ha at NyStr skal ha' består KUN af det samme antal nuller, kan du f.eks. bruge følgende:

NyStr:=StringToChar(NumLeadZero([input-streng]));
Avatar billede abpdk Nybegynder
12. august 2003 - 22:20 #6
Hov, det skulle ha' været:
Str:=StringToChar('0', NumLeadZero([input-streng]));
Avatar billede dkn Nybegynder
12. august 2003 - 22:46 #7
måske lidt hurtigere når der ikke skal konventeres.

function CounterZero(input:string):integer;
var
i :integer;
begin
result := 0;
for i:= 1 to length(input) do
  if input[I] = '0' then
    inc(result);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage(inttostr(CounterZero('000123')));
end;
Avatar billede abpdk Nybegynder
12. august 2003 - 23:08 #8
dkn>> Var meningen ikke at den skulle finde de første nuller, og ikke bare dem alle sammen?
Avatar billede doc404 Novice
13. august 2003 - 00:05 #9
Hvis du kun skal finde de første nuller i en streng så:

function CountFirstZeroes(const str : string) : integer;
var
  p : PChar;
begin
  Result := 0;
  p := PChar(str);
  while (p^ <> #00) and (p^ = '0') do
  begin
    Inc(Result);
    Inc(p);
  end;
end;
Avatar billede borrisholt Novice
13. august 2003 - 10:06 #10
Her er et par bud :

En lavet i Pascal, og en i Assembler :

function NumLeadZeroASM(Const Value : String): integer;
asm
  mov edx, $00 // Result := 0
  test eax, eax //Er strengen tom ?
  jz @@Done //Så Exit
  mov ecx,[eax - $04] // Læs længden på vores streng, og gem den i ecx
@@Again:
  cmp edx, ecx // Result < Length(Value)
  cmp byte ptr [eax + edx], $30 //Value[Result] = '0'
  jnz @@Done //Enten har vi fundet noget der ikke er et '0', eller enden er nået --> Hop til Done
  inc edx //Tæl vores tæller
  jmp @@Again //Loop
@@Done:
  mov eax, edx //Retuner værdien af vores tæller
end;

function NumLeadZero(Const Value : String): integer;
begin
  Result := 0;
  while (Value[Result + 1] = #48) and (Result < Length(Value)) do
    Inc(Result);
end;


Jens B
Avatar billede borrisholt Novice
16. august 2003 - 19:41 #11
Er du der ?
Avatar billede azs Nybegynder
20. august 2003 - 21:54 #12
uhaa da da.. jeg har ikke været hjemme de sidste par dage men jeg checker lige de ting her og ser om jeg kan få det til at virke ;)
Avatar billede azs Nybegynder
20. august 2003 - 22:11 #13
Hvilken fil kan jeg finde StringToChar i ?
Avatar billede doc404 Novice
20. august 2003 - 22:59 #14
Borrisholdt:

@@Again:
  cmp edx, ecx // Result < Length(Value)
  cmp byte ptr [eax + edx], $30 //Value[Result] = '0'
  jnz @@Done //Enten har vi fundet noget der ikke er et '0', eller enden er nået --> Hop til Done
  inc edx //Tæl vores tæller

Dine to CMP i rap går da galt...
Avatar billede athlon-pascal Juniormester
21. august 2003 - 09:06 #15
Jeg vil anbefale dig at bruge dkn's funktion:

function CounterZero(input:string):integer;
var
i :integer;
begin
result := 0;
for i:= 1 to length(input) do
  if input[I] = '0' then
    inc(result);
end;

Dernæst kan du så bruge den:
case CounterZero(NulStreng) of
  1:NyStr := '0'
  2:NyStr := '00'
  3:NyStr := '000'
  4:NyStr := '0000'
end;

Eller, endnu bedre:

var
  I: Integer;
begin
  NyStr := '';
  for I := 1 to CounterZero(NulStreng) do
    NyStr := NyStr + '0';
Avatar billede doc404 Novice
21. august 2003 - 09:13 #16
Det var antallet af foranstillede nuller azs skulle bruge. CounterZero tæller antallet af 0'er i hele strengen.
Avatar billede borrisholt Novice
21. august 2003 - 09:22 #17
athlon-pascal >> Du har ret. 2x cmp i træk viker ikke. Nå men funktionen er også mest skrevet for sjov.

Og når nu doc404 begynte med at skrive en hurtigere funktion, så ville jeg lige skrive en i Assembler :-)


function NumLeadZeroASM(Const Value : String): integer;
asm
  mov edx, $00 // Result := 0
  test eax, eax //Er strengen tom ?
  jz @@Done //Så Exit
  mov ecx,[eax - $04] // Læs længden på vores streng, og gem den i ecx
@@Again:
  cmp edx, ecx // Result = Length(Value) ?
  je @@Done //Hvis så hop til Done
  cmp byte ptr [eax + edx], $30 //Value[Result] = '0'
  jnz @@Done //Enten har vi fundet noget der ikke er et '0', eller enden er nået --> Hop til Done
  inc edx //Tæl vores tæller
  jmp @@Again //Loop
@@Done:
  mov eax, edx //Retuner værdien af vores tæller
end;


Jens B
Avatar billede athlon-pascal Juniormester
21. august 2003 - 11:05 #18
Jens -> "athlon-pascal >> Du har ret. 2x cmp i træk viker ikke. Nå men funktionen er også mest skrevet for sjov." Det var doc404 der kommenterede din Assembler-funktion, jeg forstår ikke Assembler :-)

Og lad os så lige få noget der virker:

function CounterZero(input:string):integer;
var
i :integer;
begin
result := 0;
for i:= 1 to length(input) do
  if input[I] = '0' then
    inc(result);
  else
    Break;
end;

:-)
Avatar billede borrisholt Novice
21. august 2003 - 11:51 #19
ja ja min virker altså også :-)

Jeg har indført en je @@Done  i mit loop

Jens B
Avatar billede azs Nybegynder
21. august 2003 - 13:34 #20
dkn -> jeg må afvise dit svar da den finder alle 0'er i en string og ik kun de første.

Hvis Jens lige vil lave et svar så il jeg lige dele lidt points ud ;)
Avatar billede borrisholt Novice
21. august 2003 - 15:50 #21
Jow da
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