Jak napisać funkcję, która zwraca pierwszą wolną liczbę z zakresu 0..x gdzie x to np. 10? Przykładowo chciałbym stworzyć listę jednokierunkową i każdemu elementowi podczas dodawania nadać identyfikator z ustalonego zakresu.
Wydaje mi się, że nie jest Ci do tego potrzebna funkcja, wystarczy zwykła zmienna, która będziesz iterował..
Natomiast jak już się upierasz na tą funkcję, to możesz zadeklarować tablice o rozmiarze X i (O ile to możliwe w pascalu) po prostu wpisać liczby do tablicy ,a po użyciu usuwać. (sprawdziłoby się to, gdybyś miał losowe liczby przypisywać)
Co to znaczy pierwsza wolna liczba z zakresu
?
Jaka jest pierwsza wolna liczba z zakresu <0, 5>
, (-3, 8)
czy też <0, 0>
i dlaczego?
Podczas dodawania elementu do listy jednokierunkowej przydzielam identyfikator elementowi z zakresu od 0 do 10.
Dla pierwszego elementu będzie to 0, dla drugiego 1, dla trzeciego 2 itd.
Powiedzmy, że wprowadziłem 3 elementy do listy, czyli wykorzystałem identyfikatory 0, 1, 2. Usunąłem element o id 2. Podczas dodawania kolejnego elementu do listy chciałbym aby funkcja zwróciła pierwszy wolny id czyli 2.
Zasadnicze pytanie jak takie rozwiązanie zaimplementować?
EDIT: Doczytałem...
W takim razie użyj tablicy int-ów każdemu elementowi 0 przypisz, jak użyjesz to 1. Później jak usuniesz element to znów 0. W funkcji będziesz szukał sobie w pętli, aż table[i] == 0 no i gitara.
W pascalu nie umiem programować niestety, ale w C by to wyglądało mniej więcej tak:
int FirstFreeNumber(int freeNumbers[])
{
int i=0;
while(freeNumbers[i]!=0)
i++;
return freeNumbers[i];
}
Jeśli liczb będzie poniżej 256, możesz wykorzystać zwykły wbudowany set
- przy dodawaniu do listy tworzysz taki zbiór i wypełniasz go liczbami 0-255, skanujesz całą listę usuwając zajęte idki i zwracasz potem pierwszy wolny.
Na 99% można to zrobić od FPC 2.6.4 w górę oraz od ostatnich wersji Delphi (tylko tam możliwe jest iterowanie po zbiorach).
Oczywiście na dłuższą metę wygodniej byłoby napisać własną, generyczną klasę TSet
(chyba że coś tam jest w bibliotece standardowej, nigdy nie miałem potrzeby wykorzystywać, więc nie wiem).
Jeżeli to dla przyspieszenia zadań konkursowych to:
constexpr siez_t size=1000;
struct data { int value; data *next; static data *free; } tb[size]={{0}};
int move(data *&dst,data *src&)
{
data *tmp=src->next;
src->next=dst;
dst=src;
src=tmp;
return tmp->value;
}
void push(data *&stc,int value)
{
move(stc,data::free);
stc->value=value;
}
int pop(data *&stc)
{
return move(data::free,stc);
}
void init(data tb[],size_t size)
{
for(int i=1;i<size;++i) tb[i-1].next=&tb[i];
data::free=tb[0];
}
jeżeli zaś chcesz to użyć w jakimś projekcie to ... jeszcze jeden poległ ...
Dla pascala:
type PNode=^TNode;
type TNode=record value:Integer; PNode:Next; end;
var tb:array[0..1000]of TNode;
var FreeNodes:PNode;
function Move(var dst,src:PNode):Integer;
var tmp:PNode;
begoin
tmp=src^.next;
src^.next=dst;
dst=src;
src=tmp;
Result:=tmp^.value;
end;
procedure push(var src:PNode;value:Integer);
begin
move(stc,FreeNodes);
stc^.value:=value;
end;
function pop(var src:PNode):Integer;
begin
Result:=move(FreeNodes,stc);
end;
procedure Init;
var i:Integer;
begin
for i:=Low(tb)+1 to high(tb) do tb[i-1].Next:=@tb[i];
FreeNodes:=@tb[Low(tb)];
end;
o ile niczego nie pokręciłem.