[] Data structure using python to solve the problem from three angles josephus

EDITORIAL 0

josephus problem is a common example of a data structure of materials, the problem can be described as:

Assume n n individuals sitting around now requires from k k personal Countin, the first report m m number of people quit. Then start from the next person to continue to follow the same rules as the number of newspaper and quit until everyone exit. Required output order each serial number.

An array-based solution concept

First, consider the concept of an array of fixed size and the python list based on the upcoming list seen as a fixed number of elements in an object, only to change the value without deleting the elements, put the equivalent of a circle n n chairs, chairs though people quit but still, we can give everyone from 1 1 to n n No, no one's position with 0 0 expressed ideas are as follows:

  • The initial
    establishment include n n Personal (number) of the list
    to find the first k k individuals start
  • Run
    from k k is the number of the starting position m m , encounters the intermediate 0 0 then skip
    count m m then, its value to 0 0
    then continue the cycle, total circulation n n times (because each loop will exit a person)

code show as below:

def josephus_A(n, k, m):
    people = list(range(1, (n+1)))
    i = k-1
    for num in range(n):
        count = 0
        while count < m: 
            if people[i] > 0:
                count += 1
            if count == m:
                print(people[i], end=" ")
                people[i] = 0
            i = (i+1) % n # count只是flag,真正记的数是i
        if num < n-1:
            print(end=",", )
        else:
            print(" ")

Method 2 is based on sequence table

Sequence table is a linear table, i.e. the table elements on a large enough contiguous memory area, the start position of the first element stored in the storage area, the remaining elements are sequentially stored. Sequence table in python is List, with the first solution is different when the first m m individual exit needs to operate to remove elements, is the order of the table. And the array you want to delete the first solution is not so easy, because there is no built-in support for python array, so instead of a list, specific reference may be made in the array c ++, if you want to delete an element in the middle of it, you must renumber the elements behind. Code is implemented as follows:

def josephus_L(n, k, m):
    people = list(range(1, (n+1)))
    i=k-1
    for num in range(n,0,-1):
        i=(i+m-1)%num
        print(people.pop(i),end=", " if num>1 else "\n")

3 based on the cyclic single list Solution

I.e., a one-way link list table, typically c ++ is a linked list, a single chain loop is a single chain linked end to end, the table also linear, circular using a single linked list This question recorded n n individuals sitting around the most fit. We just need to count on m m nodes are deleted, the delete operation is relatively easy for the list, and does not require i = (i + 1)%divisible by such operation. But the problem is not as c ++ and python that have built-in support for the list, it is necessary to establish a list of classes, the establishment is too much trouble, but the operation is relatively simple, as follows:

class LNode: # 建立链表结点
    def __init__(self,elem,next_=None):
        self.elem=elem
        self.next=next_
class LCList: # 建立循环链接表
    def __init__(self):
        self._rear=None
    def is_empty(self):
        return self._rear is None
    def prepend(self,elem): # 前端插入
        p=LNode(elem)
        if self._rear is None:
            p.next=p # 建立一个结点的环
            self._rear=p
        else:
            p.next=self._rear.next
            self._rear.next=p
    def append(self,elem): # 尾端插入
        self.prepend(elem)
        self._rear = self._rear.next
    def pop(self): # 前端弹出
        if self._rear is None:
            raise LinkedListUnderflow("in pop of CLList")
        p = self._rear.next
        if self._rear is p:
            self._rear =None
        else:
            self._rear.next=p.next
        return p.elem
    def printall(self): # 输出表元素
        if self.is_empty():
            return
        p = self._rear.next
        while True:
            print(p.elem)
            if p is self._rear:
                break
            p=p.next
class LinkedListUnderflow(ValueError): # 自定义异常
    pass
class Josephus(LCList):
    def __init__(self,n,k,m):
        LCList.__init__(self)
        for i in range(n):
            self.append(i+1)
        self.turn(k-1)
        while not self.is_empty():
            self.turn(m-1)
            print(self.pop(),end=("\n" if self.is_empty() else ", "))
    def turn(self,m):
        for i in range(m):
            self._rear = self._rear.next
Published 95 original articles · won praise 30 · views 40000 +

Guess you like

Origin blog.csdn.net/JohnJim0/article/details/105088977