kotlin 泛型解决擦除
Flavius Josephus是犹太裔的罗马历史学家。 在公元一世纪的犹太罗马战争期间,他与同伴士兵(共40名士兵)一起在一个山洞里,被敌方罗马军队包围。 他们决定自杀成环,并指望每三个男人自杀。 每个这样指定的人都会自杀...约瑟夫斯不想死,设法将自己置于最后一个幸存者的位置。 在问题的一般版本中,有n个从1到n编号的士兵,每第k个士兵将被淘汰。 计数从第一个士兵开始。 最后一个幸存者是多少?
测试我的建筑Kotlin技能似乎是一个很大的挑战。 这是我想出的解决方案。 首先,使用TestNG和数据提供程序的测试类-完美的用例:
classJosephusTest{
@DataProvider
fundata():Array<Array<Int>>{
returnarrayOf(
arrayOf(2,1,0),
arrayOf(3,1,0),
arrayOf(10,1,0),
arrayOf(3,2,0),
arrayOf(4,2,1)
)
}
@Test(dataProvider="data")
funcircle_of_size_and_step_should_survive_position(size:Int,step:Int,expectedPosition:Int){
valcircle=Circle(size,step)
valsurvivor=circle.findSurvivor()
assertEquals(survivor.position,expectedPosition)
}
}
现在,代码:
classSoldier(valposition:Int){
varstate=State.Living
lateinitvarnext:Soldier
funsuicide(){
state=State.Dead
}
funisDead()=state==State.Dead
}
enumclassState{
Living,Dead
}
classCircle(privatevalsize:Int,privatevalstep:Int){
privatevalfirst=Soldier(0)
init{
varperson=first
while(person.position<size-1){
person=createNext(person)
}
vallast=person
last.next=first
}
privatefuncreateNext(soldier:Soldier):Soldier{
valnew=Soldier(soldier.position+1)
soldier.next=new
returnnew
}
funfindSurvivor():Soldier{
varsoldier:Soldier=first
varnumberOfDead=0
while(numberOfDead<size-1){
varcount:Int=0
while(count<step){
soldier=nextLivingSoldier(soldier)
count++
}
soldier.suicide()
numberOfDead++
}
returnnextLivingSoldier(soldier)
}
privatefunnextLivingSoldier(soldier:Soldier):Soldier{
varcurrentSoldier=soldier.next
while(currentSoldier.isDead()){
currentSoldier=currentSoldier.next
}
returncurrentSoldier
}
}
该代码可以正常工作,并且测试成功。
但是,在尝试对解决方案进行编码时,我意识到既没有Java也没有Kotlin实施循环链表的数据结构。 因此,我必须实现自己的循环数据结构,但无需实现通用的收集功能。
现在,上述代码的问题在于,虽然我觉得Soldier
类很好,但Circle
类却没有。 Circle
var
太多,感觉就像命令式编程一样。 缺乏for(;;)
在Kotlin力量我使用while
与外部变量-两次: count
和numberOfDead
。
我一直认为我可以通过更改数据结构来改善这种情况。 我只是不知道如何...现在,Kotlin和FP专家,您有什么建议吗?
翻译自: https://blog.frankel.ch/solving-the-josephus-problem-in-kotlin/
kotlin 泛型解决擦除