forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   Послдений не Null в списке (http://forum.boolean.name/showthread.php?t=14624)

NitE 22.04.2011 19:31

Послдений не Null в списке
 
Подскажите пожалуйста, как мне из списка получить первый, не-нулевой предыдущий элемент.

current:mytype=mytype(ListFindLink(mylist,current) .prevlink().value())

Вот такой код работает отлично, пока из середины списка что-нибудь не пропадет.
К примеру у меня 4 экземпляра типа, current в данный момент 4, а 3 удаляется (т.е. listremove()), если попытатся выполнить данный код, то вылетает с ошибкой доступа к Null элементу. А надо чтобы просто проскачил на 2 элемент.

Надеюсь понятно объяснил.

Venom2 22.04.2011 21:24

Ответ: Послдений не Null в списке
 
Цитата:

Сообщение от NitE (Сообщение 186563)
Подскажите пожалуйста, как мне из списка получить первый, не-нулевой предыдущий элемент.

current:mytype=mytype(ListFindLink(mylist,current) .prevlink().value())

Вот такой код работает отлично, пока из середины списка что-нибудь не пропадет.
К примеру у меня 4 экземпляра типа, current в данный момент 4, а 3 удаляется (т.е. listremove()), если попытатся выполнить данный код, то вылетает с ошибкой доступа к Null элементу. А надо чтобы просто проскачил на 2 элемент.

Надеюсь понятно объяснил.

Лучше у каждого экземпляра MyType хранить ссылку TLink на добавляемый элемент. Тогда не надо будет использовать медленный ListFindLink, который для поиска перебирает список, и заодно решается описаная тобой проблема:

Код:

Framework BRL.Blitz
Import BRL.LinkedList

Type MyType
       
        Field Link : TLink
       
End Type

Local MyList : TList = CreateList()

Local Element1 : MyType = New MyType
Element1.Link = ListAddLast(MyList, Element1)

Local Element2 : MyType = New MyType
Element2.Link = ListAddLast(MyList, Element2)

Local Element3 : MyType = New MyType
Element3.Link = ListAddLast(MyList, Element3)

Local Element4 : MyType = New MyType
Element4.Link = ListAddLast(MyList, Element4)

Local CurrentElement : MyType = Element4

ListRemove(MyList, Element3)

CurrentElement = MyType(CurrentElement.Link.PrevLink().Value())

If CurrentElement <> Element2 Then RuntimeError("Oh shit!")

End

Естественно PrevLink() надо проверять на Null, вдруг текущий элемент окажется первым.

Черный крыс 22.04.2011 22:18

Ответ: Послдений не Null в списке
 
Опупеть...

Списки это удобный контейнер - итератор. Но чтобы ТАК извергаться над списками? заЧем? чем вас массивы не устраивают? мнгновенный индексный доступ без всяких линков...

Venom2 22.04.2011 23:03

Ответ: Послдений не Null в списке
 
Цитата:

Сообщение от Diablo1909 (Сообщение 186574)
Но чтобы ТАК извергаться над списками?

Так это как?
Цитата:

Сообщение от Diablo1909 (Сообщение 186574)
чем вас массивы не устраивают?

Каким боком массивы имеют отношение к описываемой проблеме?
Цитата:

Сообщение от Diablo1909 (Сообщение 186574)
мнгновенный индексный доступ без всяких линков...

А если нужно сохранять порядок при удалении элементов? Сортировать каждый раз будешь? Или может быть удалять смещением блока памяти, что тоже не дешево?
Для каждой задачи свой контейнер, непонятно вообще к чему твоя мессага.

Черный крыс 22.04.2011 23:27

Ответ: Послдений не Null в списке
 
Во мля... вы просто массивы юзаете как ламеры.

Venom2 22.04.2011 23:43

Ответ: Послдений не Null в списке
 
Цитата:

Сообщение от Diablo1909 (Сообщение 186580)
Во мля... вы просто массивы юзаете как ламеры.

Как был ты клоуном, так и остался :D

Черный крыс 23.04.2011 00:26

Ответ: Послдений не Null в списке
 
Для особо одаренных...

Код:


Global mass%[] = New Int[4]
Const NULL_ITEM% = -1 ' обьявляем *Null* переменную
 
MemCopy(mass, [1,2,3,4], 4*4) ' инициализируем
 
' 1) Удаляем 3-й элемент :
mass[2] = NULL_ITEM
 
' 2) Адекватный перебор с учетом удаленного
For Local i% = 0 Until mass.Length
    If mass[i] = NULL_ITEM Then Continue
    ....
Next

PS Стандартный TList - оцтой тот еще. Ты глянь на исходник его... он как мамонт жрет память и проц. Листы вообще придуманы ламерами и для ламеров - это жуткое зло - лист плодит кучу однотипных ссылок которые к тому же пересекаются и снаружи никак нельзя проконтролировать их, что чревато утечками памяти и тому подобными весельями, так как БМакс не умеет такие ссылки обрабатывать. Серия Quake 1-3 полностью реализована на массивах (насчет 4-й незнаю, но скорее всего тоже). в Unreal тоже не увидишь ни одного листа (их тама просто нет). В 99.9% листы ненужны вообще, возможностей массивов хватает слихвой и везде ( в крайнем случае можно эмитировать список односторонним указателем).

IGR 23.04.2011 02:00

Ответ: Послдений не Null в списке
 
а что правда если что то удаляется то оно Всегда превращяется в -1 ??

Черный крыс 23.04.2011 12:50

Ответ: Послдений не Null в списке
 
Цитата:

Сообщение от IGR (Сообщение 186589)
а что правда если что то удаляется то оно Всегда превращяется в -1 ??

Это не так критично. Пустые переменные как правило весят не больше 4 байт, поэтому лишняя тысяча в массиве не окажет серьезной нагрузки на систему (в отличие от листов, которые затормозят все что можно). Перебор массива по индексам (тоесть через For i%=0 Until mass.Length) происходит гораздо быстрее чем перебор листа. Доступный перебор ( тоесть For i% = EachIn mass ) по скорости такой же медленный как и листы, там за цикл происходит 2 вызова методов. Первый вариант предпочтительней, но в то же время на Ваши плечи ложится забота чтобы не вылететь за пределы массива. Более того, эти пустые ячейки массива можно заюзать позже при добавлении нового элемента, причем можно добавлять куда угодно, хоть в начало хоть в конец или в середину. Ну и в крайнем случае массив можно почистить после некоторых манипуляций над ним.

NitE 26.04.2011 01:22

Ответ: Послдений не Null в списке
 
Diablo1909, подкинешь статей (или сам напишешь)) ) про то как надо массивы по-отцовски юзать ? Будем учиться.
(Вот в данный момент например непонятно как из кастомного массива что-либо удалить. myarr:mytype[x]=-1 естественно кидает cannot convert int to mytype. Вот и хз как быть.)

Randomize 26.04.2011 12:11

Ответ: Послдений не Null в списке
 
HandleFromObject
HandleToObject

Черный крыс 26.04.2011 12:58

Ответ: Послдений не Null в списке
 
2Nite

в массивах должна хранится однотипная информация, числа с числами, обьекты с обьектами.

В примере компилятор тебе говорит что "не могу сконвертить целое число в тобою обьявленный mytype"
Так как массив обьявлен у тебя как содержащий некие обьекты, то пишем так :

Код:

myarr[x] = Null
Насчет статьи хз. Глянь лучше на исходники HGE (Партиклы). Там есть пример как юзать массивы с максимальной выгодой.

NitE 04.05.2011 22:19

Ответ: Послдений не Null в списке
 
Diablo1909, можно поподробней как не вылететь за пределы массива ?

А то ведь For i%=0 Until mass.Length значит, что он строго до длинны массива перебирает, но у меня почему-то если поменять размер массива (например укоротить его слайсом) то пишеть типа вылетел за предел.

Черный крыс 05.05.2011 00:17

Ответ: Послдений не Null в списке
 
После переразметки массива, он должен корректно возвращать длинну ( по сути это создание нового массива с новой длинной ), поэтому здесь косяков быть не должно.

Телепаты в отпуске, так что код с косяком в студию, посморим что у тебя тама.

ЗЫ Слайсы - в топку, тоже вещь очень медленная.

NitE 05.05.2011 00:58

Ответ: Послдений не Null в списке
 
Решил проблему отказавшись от слайсов. Спасибо.


Часовой пояс GMT +4, время: 02:58.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot