Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

Python에서 다른 쿼리에 대한 문자열의 다른 부분 문자열 수를 찾는 프로그램

<시간/>

길이가 n인 문자열 s가 있다고 가정합니다. 또한 Q[i]에는 (l, r) 쌍이 포함된 쿼리 Q 목록이 있습니다. 각 쿼리에 대해 l과 r 사이의 포함 범위에 있는 s의 다른 부분 문자열 수를 계산해야 합니다.

따라서 입력이 s ="ppqpp" Q =[(1,1),(1,4),(1,1),(0,2)]와 같으면 출력은 [1,8, 1,5] 때문에

  • 쿼리(1, 1)의 경우 유일한 하위 문자열은 'p'이므로 출력은 1입니다.

  • 쿼리(1, 4)의 경우 하위 문자열은 'p', 'q', 'pq', 'qp', 'pp', 'pqp', 'qpp' 및 'pqpp'이므로 출력은 8

  • 다시 쿼리(1, 1)의 경우 유일한 하위 문자열은 'p'이므로 출력은 1입니다.

  • 쿼리(0, 2)의 경우 부분 문자열은 'p', 'q', 'pp', 'pq', 'ppq'이므로 출력은 8입니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • kasai() 함수를 정의합니다. s, suff, n
  • 이 걸립니다.
  • lcp :=크기가 n이고 0으로 채워진 배열
  • inv :=크기가 n이고 0으로 채워지는 배열
  • 0 ~ n - 1 범위의 i에 대해
    • inv[suff [i]] :=나
  • k :=0
  • 0 ~ n - 1 범위의 i에 대해
    • inv [i]가 n-1과 같으면
      • k :=0
      • 다음 반복으로 이동
    • j :=suff[inv [i] + 1]
    • i + k
    • k :=k + 1
  • lcp[inv [i]] :=k
  • k> 0이면
    • k :=k - 1
  • LCP 반환
  • 메인 방법에서 다음을 수행하십시오. -
  • res :=새 목록
  • 0에서 Q - 1의 크기 범위에 있는 i에 대해
    • (왼쪽, 오른쪽) :=Q[i]
    • sub :=인덱스 왼쪽에서 오른쪽으로 s의 부분 문자열
    • 길이 :=오른쪽-왼쪽 + 1
    • 접미사 :=범위 0에서 길이 - 1까지의 각 i에 대한 쌍 목록(i, 인덱스 i에서 끝까지 sub의 부분 문자열)
    • 쌍 하위 문자열의 두 번째 항목을 기준으로 접미사 정렬
  • (suff, suffix) =인덱스 쌍 및 suffix
      의 해당 하위 문자열
    • lcp :=kasai(sub, suff, length)
    • count :=접미사[0]의 크기
    • 0에서 길이-2 사이의 i에 대해
      • count :=개수 + 접미사 크기[i + 1] - lcp[i]
    • res 끝에 카운트 삽입
  • 반환 결과
  • 이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

    def kasai (s, suff, n):
       lcp = [0] * n
       inv = [0] * n
       for i in range (n):
          inv [suff [i]] = i
       k = 0
       for i in range (n):
          if inv [i] == n-1:
             k = 0
             continue
          j = suff [inv [i] + 1]
          while i + k <n and j + k <n and s [i + k] == s [j + k]:
             k += 1
          lcp [inv [i]] = k
          if k> 0:
             k -= 1
       return lcp
    
    def solve(s, Q):
       res = []
       for i in range (len(Q)):
          left, right = Q[i]
          sub = s [left: right + 1]
          length = right-left + 1
    
          suffix = [[i, sub [i:]] for i in range (length)]
    
          suffix.sort (key = lambda x: x [1])
          suff, suffix = [list (t) for t in zip (* suffix)]
    
          lcp = kasai (sub, suff, length)
          count = len (suffix [0])
          for i in range (length-1):
             count += len (suffix [i + 1]) - lcp [i]
    
          res.append(count)
       return res
    
    s = "pptpp"
    Q = [(1,1),(1,4),(1,1),(0,2)]
    print(solve(s, Q))

    입력

    "pptpp", [(1,1),(1,4),(1,1),(0,2)]
    

    출력

    [1, 8, 1, 5]