Fix empty LIS
This commit is contained in:
parent
ae448f947f
commit
e88f9e4c96
2 changed files with 28 additions and 9 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
## Karax -- Single page applications for Nim.
|
## Karax -- Single page applications for Nim.
|
||||||
|
|
||||||
import dom, vdom, jstrutils, components, jdict, tables
|
import dom, vdom, jstrutils, components, jdict
|
||||||
|
|
||||||
export dom.Event
|
export dom.Event
|
||||||
|
|
||||||
|
|
@ -184,6 +184,9 @@ proc print(s: cstring, ident: int) =
|
||||||
# kout cstring(result)
|
# kout cstring(result)
|
||||||
|
|
||||||
proc longestIncreasingSubsequence(a: seq[int]): seq[int] =
|
proc longestIncreasingSubsequence(a: seq[int]): seq[int] =
|
||||||
|
if len(a) == 0:
|
||||||
|
return @[]
|
||||||
|
|
||||||
result.add 0
|
result.add 0
|
||||||
var parent = newSeq[int](len(a))
|
var parent = newSeq[int](len(a))
|
||||||
for i in 0..<len(a):
|
for i in 0..<len(a):
|
||||||
|
|
@ -216,6 +219,10 @@ proc longestIncreasingSubsequence(a: seq[int]): seq[int] =
|
||||||
dec pos
|
dec pos
|
||||||
|
|
||||||
proc updateElement(parent, current: Node, newNode, oldNode: VNode, ident: int = 0) =
|
proc updateElement(parent, current: Node, newNode, oldNode: VNode, ident: int = 0) =
|
||||||
|
if newNode.key != -1:
|
||||||
|
kout cstring($newNode.key)
|
||||||
|
if oldNode.key != -1:
|
||||||
|
kout cstring($oldNode.key)
|
||||||
newNode.dom = oldNode.dom
|
newNode.dom = oldNode.dom
|
||||||
if not equalsShallow(newNode, oldNode):
|
if not equalsShallow(newNode, oldNode):
|
||||||
detach(oldNode)
|
detach(oldNode)
|
||||||
|
|
@ -317,6 +324,10 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode, ident: int =
|
||||||
if not isKeyed:
|
if not isKeyed:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if rightNew - leftNew + 1 + rightOld - leftOld + 1 == 0:
|
||||||
|
isKeyed = false
|
||||||
|
|
||||||
|
|
||||||
if isKeyed:
|
if isKeyed:
|
||||||
if rightNew > leftNew:
|
if rightNew > leftNew:
|
||||||
# remove redundant old nodes
|
# remove redundant old nodes
|
||||||
|
|
@ -325,14 +336,22 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode, ident: int =
|
||||||
detach(oldNode[i])
|
detach(oldNode[i])
|
||||||
else:
|
else:
|
||||||
# permute elements using LIS
|
# permute elements using LIS
|
||||||
var positionByKey = newTable[VKey, int]()
|
var positionByKey = newJDict[VKey, int]()
|
||||||
var positions = newSeq[int]()
|
var positions = newSeq[int]()
|
||||||
for i in leftOld..rightOld:
|
for i in leftOld..rightOld:
|
||||||
positionByKey[oldNode[i].key] = i
|
positionByKey[oldNode[i].key] = i
|
||||||
for i in leftNew..rightNew:
|
for i in leftNew..rightNew:
|
||||||
if positionByKey.hasKey(newNode[i].key):
|
if positionByKey.contains(newNode[i].key):
|
||||||
positions.add positionByKey[newNode[i].key]
|
positions.add positionByKey[newNode[i].key]
|
||||||
|
|
||||||
|
#if len(positions) > 0:
|
||||||
|
# kout cstring("new segment len = " & $(rightNew - leftNew + 1))
|
||||||
|
# kout cstring("old segment len = " & $(rightOld - leftOld + 1))
|
||||||
|
# var t = ""
|
||||||
|
# for i in 0..<len(positions):
|
||||||
|
# t.add($positions[i] & " ")
|
||||||
|
# kout cstring(t)
|
||||||
|
|
||||||
var lis = longestIncreasingSubsequence(positions)
|
var lis = longestIncreasingSubsequence(positions)
|
||||||
var lisPos = 0
|
var lisPos = 0
|
||||||
var isNotRedundant = newSeq[bool](rightOld - leftOld + 1)
|
var isNotRedundant = newSeq[bool](rightOld - leftOld + 1)
|
||||||
|
|
@ -344,14 +363,14 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode, ident: int =
|
||||||
updateElement(current, oldNode[index].dom, newNode[i], oldNode[index], ident + 1)
|
updateElement(current, oldNode[index].dom, newNode[i], oldNode[index], ident + 1)
|
||||||
inc lisPos
|
inc lisPos
|
||||||
else:
|
else:
|
||||||
if positionByKey.hasKey(newNode[i].key):
|
if positionByKey.contains(newNode[i].key):
|
||||||
var oldPos = positionByKey[newNode[i].key]
|
var oldPos = positionByKey[newNode[i].key]
|
||||||
isNotRedundant[oldPos - leftOld] = true
|
isNotRedundant[oldPos - leftOld] = true
|
||||||
current.insertBefore(oldNode[oldPos].dom, oldNode[index].dom)
|
current.insertBefore(oldNode[oldPos].dom, oldNode[index].dom)
|
||||||
else:
|
else:
|
||||||
current.insertBefore(vnodeToDom(newNode[i]), oldNode[index].dom)
|
current.insertBefore(vnodeToDom(newNode[i]), oldNode[index].dom)
|
||||||
else:
|
else:
|
||||||
if positionByKey.hasKey(newNode[i].key):
|
if positionByKey.contains(newNode[i].key):
|
||||||
var oldPos = positionByKey[newNode[i].key]
|
var oldPos = positionByKey[newNode[i].key]
|
||||||
isNotRedundant[oldPos - leftOld] = true
|
isNotRedundant[oldPos - leftOld] = true
|
||||||
current.appendChild(oldNode[oldPos].dom)
|
current.appendChild(oldNode[oldPos].dom)
|
||||||
|
|
|
||||||
|
|
@ -83,16 +83,16 @@ proc test4() =
|
||||||
timeout = setTimeout(check4, 20)
|
timeout = setTimeout(check4, 20)
|
||||||
|
|
||||||
proc check5() =
|
proc check5() =
|
||||||
let result = checkOrder(@[0, 1, 3, 5, 4, 5])
|
let result = checkOrder(@[0, 1, 3, 5, 4, 8])
|
||||||
if result:
|
if result:
|
||||||
results.add cstring"test5 - OK"
|
results.add cstring"test5 - OK"
|
||||||
else:
|
else:
|
||||||
results.add cstring"test5 - FAIL"
|
results.add cstring"test5 - FAIL"
|
||||||
|
|
||||||
# result: 0 1 3 5 4 5
|
# result: 0 1 3 5 4 8
|
||||||
proc test5() =
|
proc test5() =
|
||||||
results.add cstring"test5 started"
|
results.add cstring"test5 started"
|
||||||
entries = @[cstring("0"), cstring("1"), cstring("3"), cstring("5"), cstring("4"), cstring("5") ]
|
entries = @[cstring("0"), cstring("1"), cstring("3"), cstring("5"), cstring("4"), cstring("8") ]
|
||||||
redraw()
|
redraw()
|
||||||
timeout = setTimeout(check5, 20)
|
timeout = setTimeout(check5, 20)
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ proc test7() =
|
||||||
|
|
||||||
proc createEntry(id: int): VNode =
|
proc createEntry(id: int): VNode =
|
||||||
result = buildHtml():
|
result = buildHtml():
|
||||||
button(id="" & $id):
|
button(id="" & $id, key = id):
|
||||||
text $id
|
text $id
|
||||||
|
|
||||||
proc createDom(): VNode =
|
proc createDom(): VNode =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue