สมมติว่าเราต้องสร้างตัววนซ้ำที่วนซ้ำผ่านลำดับการเข้ารหัสแบบรัน-ยาว ในที่นี้ ตัววนซ้ำจะเริ่มต้นโดยการเรียก RLEIterator(int[] A) โดยที่ A คือการเข้ารหัสความยาวรันของลำดับ ดังนั้นเราสามารถพูดได้ว่าสำหรับแม้แต่ i ทั้งหมด A[i] บอกเราถึงจำนวนครั้งที่ค่าจำนวนเต็มไม่เป็นลบ A[i+1] ซ้ำกันในลำดับ นี่ iterator รองรับหนึ่งฟังก์ชัน -
-
ถัดไป (int n):ฟังก์ชันนี้ทำให้องค์ประกอบ n ถัดไปหมด (n>=1) และส่งคืนองค์ประกอบสุดท้ายที่หมดด้วยวิธีนี้ ดังนั้นหากไม่มีองค์ประกอบเหลือที่จะระบายออก ครั้งต่อไปจะคืนค่า -1 แทน
สมมติว่าเราเริ่มต้นด้วย A =[3,8,0,9,2,5] ซึ่งเป็นการเข้ารหัสตามความยาวของลำดับ [8,8,8,5,5] สิ่งนี้ทำได้เนื่องจากลำดับสามารถอ่านได้ว่า "สามแปด ศูนย์เก้า สองห้า" ดังนั้น หลังจากที่เริ่มต้นด้วย A แล้ว หากเราเรียก next(2), next(1), next(1), next(2) ผลลัพธ์สุดท้ายจะเป็น [8, 8, 5, -1]
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
ใน initializer ให้เริ่มต้นอาร์เรย์เป็น A และตั้งค่าดัชนี :=0
-
ในเมธอด next() จะใช้ n เป็นอินพุต สิ่งนี้จะทำงานดังนี้
-
ขณะที่ดัชนี <ขนาดของ A และ n> A[ดัชนี]
-
n :=n – A[index] และเพิ่มดัชนีอีก 2
-
-
ถ้า index> ขนาดของอาร์เรย์ A ให้คืนค่า -1
-
A[index] :=A[index] – n
-
ส่งคืน A[ดัชนี + 1]
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; class RLEIterator { public: vector <int> A; int idx = 0; RLEIterator(vector<int>& A) { this->A = A; idx = 0; } int next(int n) { while(idx < A.size() && n > A[idx]){ n -= A[idx]; idx += 2; } if(idx >= A.size()) return -1; A[idx] = A[idx] - n; return A[idx + 1]; } }; main(){ vector<int> v = {3,8,0,9,2,5}; RLEIterator ob(v); cout << (ob.next(2)) << endl; cout << (ob.next(1)) << endl; cout << (ob.next(1)) << endl; cout << (ob.next(2)) << endl; }
อินพุต
Initialize with [3,8,0,9,2,5] and call next(2), next(1), next(1), next(2)
ผลลัพธ์
8 8 5 -1