[] 데이터 구조 세프 세 각도에서 문제를 해결하기 위해 사용 파이썬

사설 0

세프 문제는 재료의 데이터 구조의 공통적 인 예는,이 문제는 다음과 같이 설명 될 수있다 :

설정 개인의 주위에 지금부터 필요 앉아 케이 케이 개인 Countin 첫 번째 보고서 m 미디엄 사람의 수를 종료합니다. 그리고 신문의 수와 같은 규칙을 따르 모두 종료 될 때까지 종료 계속해서 다음 사람에서 시작합니다. 필요한 출력 순서, 각 일련 번호.

어레이 기반 솔루션 개념

먼저, 원 상당 넣어 요소만을 삭제하지 않고 값을 변경하기 위해 고정 크기와 목적의 요소의 고정 된 숫자로 본 다가오는리스트에 기초 파이썬리스트의 배열의 개념을 고려 n 의자, 의자는 사람들은 종료하지만 여전히, 우리는에서 모두를 제공 할 수 있습니다 1 1 n 아니, 아니 하나의 위치 0 0 는 다음과 같이 표현 된 개념이다 :

  • 초기
    설정은 다음과 같습니다 n 목록의 개인 (수)
    첫 번째를 찾을 수 k 케이 개인 시작
  • 실행
    에서 k 케이 시작 위치의 개수 m 미디엄 중간 발생 0 0 후 스킵
    카운트 m 미디엄 다음 해당 값을 0 0
    다음주기를 계속, 총 순환 n 회 (각 루프가 사람을 종료합니다 때문에)

다음과 같이 코드입니다 :

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(" ")

방법 2는 순서 테이블에 기초

순서 표는 충분한 연속 기억 영역에 나타난 소자는 상기 기억 영역에 저장된 첫 번째 요소의 개시 위치는, 나머지 요소들이 순차적으로 저장되어있는, 즉 선형 테이블이다. 최초의 솔루션이 다른 파이썬에서 순서 표, 목록 때 첫 m 미디엄 개별 출구 요소를 제거하도록 동작 할 필요가있는 테이블의 순서이다. 그리고 당신은 최초의 솔루션을 삭제하려는 배열이 당신이 그것의 중간에 요소를 삭제하려면 특정 참조가, 배열 C ++에서 만들어 질 수있다, 어떤이 내장되어 있기 때문에 지원 파이썬 배열, 그래서 대신 목록으로, 너무 쉽게하지 않습니다, 당신은 뒤에 요소 번호를 다시 지정해야합니다. 다음과 같이 코드가 실행된다 :

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 단에서 환상 솔루션 기반

즉, 단방향 링크리스트 테이블은, 일반적으로 C ++은 연결리스트 단일 쇄 루프 단부에 단일 쇄 결합 단부는 테이블은, 선형이 질문에 녹화 한 링크리스트를 사용하여 원형 n 개인이 가장 적합 주위에 앉아. 우리는 믿을 필요 m 미디엄 노드가 삭제되고, 삭제 동작은리스트를 비교적 용이하며, 전 (I + 1) % = 요구하지 않는등의 조작에 의해 나눌 수있다. 그러나 문제는 C ++ 및 내장 한 목록에 대한 지원,이 클래스의 목록을 구축하는 것이 필요하다 파이썬으로하지 않습니다, 설립은 너무 많은 문제가 있지만 다음과 같은 작업은 비교적 간단하다 :

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
게시 95 개 원래 기사 · 원 찬양 30 ·은 40000 +를 볼

추천

출처blog.csdn.net/JohnJim0/article/details/105088977