Permalänk
Medlem

Unika namn

Jag har en lista fylld med en massa strängar. Då jag lägger till en sträng vill jag att den ska 'heta' "ClipTab#", där # ska vara ett nummer från ett och upp. Och tar man bort strängen "ClipTab2" så ska det 'namnet' bli tillgängligt, och nästa nya sträng ska altså få det, och inte tex ClipTab23.

Det blev extremt rörigt, det där, men målet är att undvika att två eller fler strängar i listan ska vara likadana.

Jag har försökt med koden nedan, som inte fungerar, och jag börjar bli less på att stirra på den och försöka hitta felet.

"Tabs" är altså listan, och "s" är strängen som kommer att läggas till i den.

var i, k, antal : integer; s : string; begin i:=0; antal:=tabs.Items.Count; k:=i; while i<antal do begin while (tabs.Items[k]<>'ClipTab'+inttostr(i)) and (k<antal-1) do inc(k); inc(i); end; s:='ClipTab'+IntToStr(i);

Språket är Delphi, men det är enkelt att översätta till tex c++, så det är en ganska enkel snutt.

Ser ni vad som är felet?

Visa signatur
Permalänk
Medlem

hmm... är det ett stort project? du kan skicka det till mej om du vill så ska jag kolla på det... lite enklare att förstå om man ser helheten... jag förstod inte så mkt av det där nämnligen

skicka till nasso@troingehills.com om du vill så tittar jag på det...

Permalänk
Medlem

du vill alltså loopa till du hittar en ledig plats?
borde det inte vara:

while (tabs.Items[k]='ClipTab'+inttostr(i)) and (k<antal-1) do

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
du vill alltså loopa till du hittar en ledig plats?
borde det inte vara:

while (tabs.Items[k]='ClipTab'+inttostr(i)) and (k<antal-1) do

Precis, loppa tills det kommer en "namnlucka"...
Din kod fungerade lite halvt, jag försökte med den förut, men resultatet blir denna:

(Listan ser ursprungligen ut så här:)
----------
string1
item3
kalle25
hejsan
----------

Jag lägger till en sträng med hjälv av koden jag vill ha fram, och då ser listan ut så här:
----------
string1
item3
kalle25
hejsan
ClipTab4
----------

Redan där är det altså fel. Namnet borde bli ClipTab1.

Jag lägger till några fel:
----------
string1
item3
kalle25
hejsan
ClipTab4
ClipTab5
ClipTab6
ClipTab7
----------

Det fungerar som sagt "lite", den räknar upp iaf.

Men tar jag bort exempelvis ClipTab5, så får den kommande strängen namnet ClipTab7. Lägger jag till ytterliga strängar, så ser listan då ut så här:
----------
string1
item3
kalle25
hejsan
ClipTab4
ClipTab6
ClipTab7
ClipTab7
ClipTab8
ClipTab9
----------

Den fortsätter att räkna upp, men missar helt att platserna ClipTab1-ClipTab3, samt ClipTab5, är lediga.

Visa signatur
Permalänk
Medlem

Nu kan jag ingen Delphi men du verkar inte ha fått while looparna att fungera riktigt som du vill. Kanske ska det vara något liknande: (hoppas att det kan hjälpa dig lite på traven) Problemet är iaf att din första loop kommer gå igenom alla poster och i = antal rader därav kan du inte sätta s:='ClipTab'+IntToStr(i); eftersom i alltid kommer att vara summa av alla rader eller tänker jag fel då?

var i, antal : integer; s : string; !!! Deklarera bool_break här !!! begin i:=0; antal:=tabs.Items.Count; while i<antal do and bool_break <> true begin if tabs.Items[i]<>'ClipTab'+inttostr(i)) then bool_break = true end if inc(i); end; s:='ClipTab'+IntToStr(i);

Edit: ändrade koden lite. Du får ursäkta att det är lite VB i mitten där men som sagt kan inte Delphi och du förstår nog iaf

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
Nu kan jag ingen Delphi men du verkar inte ha fått while looparna att fungera riktigt som du vill. Kanske ska det vara något liknande: (hoppas att det kan hjälpa dig lite på traven) Problemet är iaf att din första loop kommer gå igenom alla poster och i = antal rader därav kan du inte sätta s:='ClipTab'+IntToStr(i); eftersom i alltid kommer att vara summa av alla rader eller tänker jag fel då?

var i, antal : integer; s : string; !!! Deklarera bool_break här !!! begin i:=0; antal:=tabs.Items.Count; while i<antal do and bool_break <> true begin if tabs.Items[i]<>'ClipTab'+inttostr(i)) then bool_break = true end if inc(i); end; s:='ClipTab'+IntToStr(i);

Edit: ändrade koden lite. Du får ursäkta att det är lite VB i mitten där men som sagt kan inte Delphi och du förstår nog iaf

Jag har konverterat koden till Delphi som jag tror att du menade, och som resultat heter varje ny sträng "ClipTab1"...

Du får gärna skriva funktionen helt i basic, så det är lättare att läsa och översätta än en 'mixad' snutt.

Hur som hellst, tackar för hjälpen.

var i, antal : integer; s : string; bool_break: boolean; begin i:=0; antal:=tabs.Items.Count; while (i<antal) and (bool_break=false) do begin if tabs.Items[i]<>'ClipTab'+inttostr(i) then bool_break:=true; inc(i); end; s:='ClipTab'+IntToStr(i); end;

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av s.c.s.i.
Jag har konverterat koden till Delphi som jag tror att du menade, och som resultat heter varje ny sträng "ClipTab1"...

Du får gärna skriva funktionen helt i basic, så det är lättare att läsa och översätta än en 'mixad' snutt.

Hur som hellst, tackar för hjälpen.

var i, antal : integer; s : string; bool_break: boolean; begin i:=0; antal:=tabs.Items.Count; while (i<antal) and (bool_break=false) do begin if tabs.Items[i]<>'ClipTab'+inttostr(i) then bool_break:=true; inc(i); end; s:='ClipTab'+IntToStr(i); end;

Edit: Jag kan inte förstå hur detta kan uppnås utan två loopar; i nuvarande läger kollar den väl bara om string 1 heter ClipTab1, string 2 ClipTab2, string 3 ClipTab3 osv...

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av s.c.s.i.
Edit: Jag kan inte förstå hur detta kan uppnås utan två loopar; i nuvarande läger kollar den väl bara om string 1 heter ClipTab1, string 2 ClipTab2, string 3 ClipTab3 osv...

Var det inte det du ville då? Jag kanske har fattat dig helt fel.

EDIT: Glöm det jag fattar nu vänta lite

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
EDIT: Glöm det jag fattar nu vänta lite

Det får vi allt hoppas..

Jag har jäklats med det (måttligt) i flera dagar, så nu är jag lagomt less, och vill gärna få lösningen serverat på ett silverfat.

Visa signatur
Permalänk
Medlem

Ok så här skulle jag ha gjort det i VB har inte möjlighet att testa koden just nu så ev missar bjuder jag på.

dim i as integer, k as integer, antal as integer dim s as string i = 0 k = 0 antal = tabs.items.count do while i<antal if tabs.Items[i] = "ClipTab" & cstr(i) then if i-k > 1 then k = k +1 exit do else k = i + 1 end if end if i = i + 1 loop s = "ClipTab" & k

Edit: jag hoppas att jag har förståt vad du ville

Så här hade jag tänkt. Loopa igenom antal rader. Hittar den en som matchar så sätt k till det värdet plus ett och fortsätt att loopa. Hittar den en till så kollar vi om den nuvarande positionen i minus den gamla k är större än 1 då vet vi om det finns en ledig på k +1 och avbryter loopen. Är däremot i - k mindre än 1 så finns det ingen ledig emellan och vi plussar bara på k och fortsätter. Skulle loopen gå igenom utan en match har vi redan satt k till 0 så strängen blir ClipTab 0 vill man inte ha nollan så kan man alltid fixa en if sats där.

Tänker vi lika nu?

Visa signatur
Permalänk
Medlem

Nu blir resultatet alltid "ClipTab0".

Jag är osäker på hur förljande kod ska översättas, så jag kan ha gjort fel där:

if i-k > 1 then k = k +1 exit do else k = i + 1 end if

Det hade varit självklart om inte för "exit do"... vad fasen gör det?

Min översättning, om den nu ger nåt:

if i-k > 1 then k := k +1 else k := i + 1;

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8

Så här hade jag tänkt. Loopa igenom antal rader. Hittar den en som matchar så sätt k till det värdet plus ett och fortsätt att loopa. Hittar den en till så kollar vi om den nuvarande positionen i minus den gamla k är större än 1 då vet vi om det finns en ledig på k +1 och avbryter loopen. Är däremot i - k mindre än 1 så finns det ingen ledig emellan och vi plussar bara på k och fortsätter. Skulle loopen gå igenom utan en match har vi redan satt k till 0 så strängen blir ClipTab 0 vill man inte ha nollan så kan man alltid fixa en if sats där.

Tänker vi lika nu?

Absolut, men i praktiken vill det sig inte. Förstog inte en vb-rad, förmodligen det som är felet.

Visa signatur
Permalänk
Medlem

Nja du kanske har rätt att den blir 0. Förmodlingen så måste man ha en till loop. Håller på att installera VB nu. Nu har du ju fått mig fast i det här med

edit: exit do hoppar ur loopen bara

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
Nja du kanske har rätt att den blir 0. Förmodlingen så måste man ha en till loop. Håller på att installera VB nu. Nu har du ju fått mig fast i det här med

Hehe, det är irriterande att ha ett sådant här problem liggandes, man går runt och funderar på det, lite svårt att bli av med tanken.

Jag tycker att man borde ha två lopar, som sagt, en som får genom alla strängar, och en som går genom nummer som ska finnas i slutet på ClipTab-strängen.

Edit: Tufft att man kan hjälpa varandra, trotts att man kan olika språk. Visserligen är de ganska lika varandra, men endå...

Visa signatur
Permalänk
Medlem

Kommer cliptab2 komma direkt efter cliptab1 i listan eller kan de vara sorterade hur som helst i listan?

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
Kommer cliptab2 komma direkt efter cliptab1 i listan eller kan de vara sorterade hur som helst i listan?

De kan ligga hur som hellst i listan. Och som sagt, listan kan innehålla strängar som inte heter ClipTab#.

Visa signatur
Permalänk
Medlem

Fick en uppenbarelse vid 2-tiden när jag skulle sova vi har ju tänkt fel hela tiden. Så här ska det vara:

Dim i As Integer, k As Integer, antal As Integer Dim s As String Dim bool_found As Boolean i = 0 'Fejka en list box med en array för testprogrammet TabsItem = Array("cliptab1", "cliptab11", "cliptab4", "cliptab3", "cliptab5", "cliptab7", "cliptab2", "cliptab8", "cliptab9", "cliptab0") 'Ubound(array) får vara Tabs.Items.Coun antal = UBound(TabsItem) 'Ändrade lite och kör en do loop och en for loop 'Lägg märke till att ci istället för att jämföra nu letar efter en match i hela ' Arrayen och hittar vi en match forsätter vi och testar nästa cliptab & cstr(i) Do While i < antal bool_found = False For k = 0 To antal 'Här ändrarde jag ordning på if satsen 'Istället för if TabsItem(i) = "cliptab" & cstr(k) så kör vi If "cliptab" & CStr(i) = TabsItem(k) Then bool_found = True 'Hittar en match k = antal 'Sätt k till antal så vi kommer ur loopen behöver inte leta mera efter denna eftersom den redan är använd End If Next k 'Om vi tagit oss igenom for loopen utan att hitta en match If bool_found = False Then s = cliptab & CStr(i) 'Sätt s till nuvarande värde Exit Do 'Hoppa ur do loopen du får fixa det i din while sats om exit do inte finns i Delphi End If 'Om vi har hittat en match testar vi nästa värde i = i + 1 Loop 'Visa en ruta med första lediga plats i arrayen MsgBox s

Vill du så kan du testa min kod genom att spara den i en textfil med ändelsen .vbs och bara dubbelklicka på den. Skrik till om du behöver VB till Delphi översättningshjälp

Visa signatur
Permalänk
Medlem

Jag slängde ihop ett litet demo i VB så om du inte får det att fungera i Delphi kan du väll ladda hem
http://hem.passagen.se/azasel/install.zip
och kolla så att vi tänker lika. Som det är nu så är det bara om den nya strängen heter något med cliptab som den lägger till en siffra efter. Du kanske ville ha så den ska leta efter kopior av alla nya strängar?

Visa signatur
Permalänk
Medlem

Tack för att tar dig tid! Har tyvärr ingen möjlighet att testa carken demot eller koden för tillfället, men jag rapporterar om några timmar.

Men det låter som att du har förstått vad jag är ute efter.

Visa signatur
Permalänk
Medlem

Hehe inga problem jag blev så fast i ditt problem att jag inte kunde ge mig innan jag löste det. Är just nu inne i en "koda massa kod" period men kommer inte på något eget bra projekt

Visa signatur
Permalänk
Medlem
Citat:

Ursprungligen inskrivet av xtermin8
Hehe inga problem jag blev så fast i ditt problem att jag inte kunde ge mig innan jag löste det. Är just nu inne i en "koda massa kod" period men kommer inte på något eget bra projekt

Jag vet hur det känns, man känner sig riktigt programmeringssugen, men man kommer inte på vad man ska göra. Tur att jag har haft ShirusuPad att jobba med ett tag nu.

Får jag fråga, efter att du förstod vad jag var ute efter (testade just demot, precis vad jag ville ha fram), hur lång tid tog det innan du knäckte det? Vill bara få en uppfattning om vart jag ligger någonstans..

Visa signatur
Permalänk
Medlem

Satt från 23 till klockan 2 igår natt sen kom jag på att jag skulle upp och jobba klockan 8 idag gick och borstade tänderna och fick under tiden en konstig känsla av att jag tänkt fel hela tiden blev nog lite lurad av din kod som du postade först. Bestämde mig sen att slänga all kod och rensa mitt minne. Gick och la mig och kom strax därefter på precis hur det skulle vara.
Klev upp tidigt för att hinna koda lite innan jobbet och visst funkade utan problem.

Problemet med din första kod är att du testar din sträng lite bakofram. Kolla bara igenom tablistan om den nya strängen finns gör den inte det lägg till den och avbryt alla loopar finns strängen så loopa igen med plussa på tilläggssiffran med 1. Vet inte hur jag ska förklara hur din nuvarande loop fungerar och vad som är fel på den men man kanske kan säga så här du får ingen kontroll på om den nya strängen finns med längre bak i listan utan du kommer bara att välja den första lediga platsen efter föregående post i listan.

EDIT: Lite fel där såg inte att du sker efter att jag förstått vad du ville ha. Kanske tog en timme att knäcka det och testa allt så det verkligen blev riktigt. Det är hemskt lätt att stirra sig blind på saker och ting när man programmerar. Är det bara en liten kod snutt man fastnar i är det oftast bäst att slänga all kod som jävlas göra något annat ett tag och börja om från början när man glömt bort den kod som jävlades

Visa signatur
Permalänk
Medlem

Konverterade just koden till Delphi utan problem, och det fungerade hur fint som hellst.

När jag nu tittar på det i pascal-form ser det ju så självklart ut. Fattar inte riktigt hur jag kunde förbise det. Som du säger, börjar det jävlas ordentligt så ska man ta en liten paus, och därefter börja om. För om man från början börjar på fel sätt (och övertygar sig själv att man tänker helt rätt), så stannar man kvar i det tankesättet, och funderar inte alls på alternativa sätt...

Hur som hellst, tack för hjälpen än en gång.

Hehe, efter alla försök så måste jag ju bara posta den riktiga Delphi-koden:

var i,k,antal: integer; s: string; bool_found: boolean; begin i:=0; antal:=tabs.Items.Count; while i<antal do begin bool_found := False; k:=0; while k<antal do begin If 'ClipTab' + IntToStr(i) = tabs.Items[k] Then begin bool_found := True; k := antal; end; inc(k); end; If bool_found = False Then begin s := 'ClipTab' + inttostr(i); i:=antal; end; inc(i); end; tabs.Items.Add(s); end;

Visa signatur
Permalänk
Medlem

Fint att du fick det att fungera tillsist.

Visa signatur