소개: 시퀀스를 생성할 수 있는 라이브러리를 인터넷에서 검색하면 거의 찾을 수 없습니다. 하지만 시퀀스는 이산수학과 컴퓨터 과학의 핵심 개념입니다. 이 짧은 기사에서는 이라는 시퀀스 생성을 위해 제가 작성한 라이브러리를 살펴보겠습니다. SeqGen 시퀀스란 무엇입니까? 시퀀스(비공식적으로 말하면)는 각 요소의 생성이 이전 요소를 기반으로 하는 요소 집합(주로 숫자)입니다. 가장 기본적인 예는 첫 번째 요소가 0이고 다음 요소가 이전 요소에 1을 더한 양의 정수의 간단한 선형 시퀀스이므로 첫 번째 요소에 1을 더하여 두 번째 요소를 얻을 수 있고 세 번째 요소를 얻을 수 있습니다. 두 번째 요소에 1을 추가하는 방식으로 요소를 구성합니다. 선형 시퀀스는 다음과 같습니다: . {0, 1, 2, 3, …, n} 더 복잡한 예는 처음 두 요소가 0과 1이고 다음 요소가 이전 두 요소의 합인 피보나치 수열일 수 있습니다. 피보나치 수열은 다음과 같습니다: {0, 1, 1, 2, 3, 5, 8, 13, 21, …, n} 위에서 시퀀스는 두 가지 속성으로 정의되어 있음을 알 수 있습니다. 초기 요소 다음 요소를 생성하는 함수 라이브러리 사용: 2.0_ 종속성: SeqGen 라이브러리는 Rust 프로그래밍 언어로 작성되었습니다. 후속 조치를 취하려면 있어야 합니다. Rust가 설치되어 2.1_ 프로젝트 생성: SeqGen 라이브러리를 사용하기 위해 새 프로젝트를 만들어 보겠습니다. 화물로 그렇게 할 수 있습니다: $ cargo new --bin sequence && cd sequence 이제 프로젝트에 종속성으로 라이브러리를 추가해 보겠습니다. $ cargo add seqgen 이제 라이브러리를 사용할 준비가 되었습니다. 시퀀스 생성: SeqGen에서 시퀀스 생성 프로세스는 시퀀스란 무엇입니까 섹션에서 결론을 내린 시퀀스의 두 가지 속성에 직접 매핑됩니다. 초기 요소와 다음 요소를 생성하는 함수(SeqGen에서는 전환 함수라고 함)를 정의해야 합니다. 선형 시퀀스를 만들어 보겠습니다. use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new() .initial_elements(vec![0]) .transition_function(|alive_elements, current_element_index| { alive_elements.last_element().unwrap() + 1 }); } 유형은 시퀀스를 나타내는 구조체입니다. 이 유형에 대해 연관된 함수 호출하면 정의되지 않은 새 인스턴스를 얻습니다. 정의되지 않은 이 인스턴스에서는 메서드를 호출하여 정의할 수 있습니다. Sequence new() 첫 번째 메소드는 요소의 벡터를 인수로 받아들이고 이를 인스턴스의 초기 요소로 설정하는 입니다. initial_elements() 두 번째 메소드는 현재 사용 가능한 요소에서 다음 요소로의 전환을 나타내는 클로저를 인수로 사용하는 입니다. transition_function() 이 클로저는 두 개의 인수에 액세스할 수 있습니다. 첫 번째는 현재 사용 가능한 요소를 나타내는 이고, 두 번째는 생성 중인 현재 요소의 인덱스인 ( 유형)입니다. 전환 기능에 대한 설명은 아래 표를 참조하세요. alive_elements current_element_index usize 현재 세대 요소 살아있는_요소 현재_요소_색인 1 [0] 1 2 [0, 1] 2 3 [0, 1, 2] 3 n [0, 1, 2, 3, …, n] n 는 유형입니다. 이 기사의 뒷부분에서 유형을 살펴보겠습니다. alive_elements SequencePart SequencePart 요소의 인덱스는 선형 시퀀스의 값이기도 하므로 위의 예를 다음과 같이 단순화할 수 있습니다. use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); } 여기서는 초기 요소를 정의할 필요가 없으며 라이브 요소에 액세스할 필요도 없습니다. 우리는 인덱스(이 경우 이름은 )만 필요하고 간단히 반환합니다. i 같은 방식으로 피보나치 수열을 정의할 수 있습니다. use seqgen::prelude::*; fn main() { let fib_seq = Sequence::new() .initial_elements(vec![0, 1_u128]) .transition_function(|alive_elements, i| { let x = alive_elements.nth_element(i - 1).unwrap(); let y = alive_elements.nth_element(i - 2).unwrap(); x + y }); } 피보나치 수열은 기하급수적으로 증가하므로 이 정의로 187개 이상의 요소를 생성하면 오버플로됩니다. 더 나은 정의는 대신 big int를 사용하는 것입니다. u128 u128 : 시퀀스 사용 시퀀스를 정의한 후에는 해당 요소에 액세스할 수 있습니다. use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); let some_element = linear_seq.nth_element(111); println!("{some_element}"); } 여기서는 요소에 대한 불변 참조(이 경우 )를 반환하는 메서드를 사용하여 111번째 요소에 액세스하고 있습니다. &usize nth_element() 변경 가능하게 만들었습니다. 그 이유는 메서드가 시퀀스의 활성 요소를 변경하기 때문입니다. linear_seq nth_element() 이러한 방식으로 시퀀스의 모든 요소에 액세스할 수 있습니다(인덱스가 인 요소부터 인덱스가 인 요소까지). 0 usize::MAX Rust 반복자처럼 시퀀스를 반복할 수도 있습니다. use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); linear_seq.for_each(|e| println!("{e}")); } 이 코드는 시퀀스의 모든 요소를 인쇄합니다(요소 부터 요소까지). 0 usize::MAX $ cargo run -q 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ... 다음 코드를 사용하여 시퀀스에서 홀수 요소를 가져올 수 있습니다. use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); let odd_elements = linear_seq.filter(|e| e % 2 != 0); odd_elements.for_each(|e| println!("{e}")); } 산출: $ cargo run -q 1 3 5 7 9 11 13 ... 우리가 정의하는 시퀀스는 게으르다. 즉, 필요하거나(반복의 경우) 명시적으로 요청하지 않는 한( 메서드 사용) 요소가 생성되지 않는다는 의미입니다. nth_element() : 시퀀스의 일부 작업 때로는 시퀀스의 일부로만 작업해야 하는 경우도 있습니다. 이 경우에는 시퀀스 부분이 있습니다. 시퀀스 부분에는 세 가지 유형이 있습니다. AliveElementsPart ImmutableRangePart MutableRangePart AliveElements부분: 시퀀스에서 메서드를 사용하여 라이브 요소를 가져올 수 있습니다. alive_elements() use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new() .transition_function(|_, i| i) .pre_generate(111); let alive_elements = linear_seq.alive_elements(); for alive_element in alive_elements { print!("{alive_element} "); } } 이 코드는 모든 활성 요소(이 경우 111개 요소를 미리 생성했기 때문에 0~110)를 인쇄합니다. 불변 범위 부분: 불변 범위는 살아있는 요소의 범위입니다. 시퀀스를 변경할 수 없습니다. 불변 범위를 생성하고 해당 요소 중 일부가 활성화되지 않은 경우 오류( 오류)가 발생합니다. DeadRange 반환하는 메서드를 사용하여 불변 범위를 만들 수 있습니다. 변형은 이고 변형은 입니다. 는 변형(범위의 시작이 끝보다 큰 경우)이거나 변형(범위의 모든 요소가 살아 있지 않은 경우)일 수 있습니다. Result range() Ok ImmutableRangePart Err RangeError RangeError InvalidRange DeadRange use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); let range = linear_seq.range(0, 3).unwrap(); for e in range { println!("{e}") } } 이 코드는 살아있는 요소가 없기 때문에 오류로 인해 패닉이 발생합니다. 다음과 같이 이를 수정할 수 있습니다. DeadRange use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); linear_seq.generate(3); let range = linear_seq.range(0, 3).unwrap(); for e in range { println!("{e}") } } 여기서는 범위를 유효하게 만들기 위해 3개의 요소를 생성했습니다. 가변 범위 부분: 변경 가능한 범위는 시퀀스를 변경(요소 생성)할 수 있습니다. 다음과 같이 변경 가능한 범위를 사용할 수 있습니다. use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); let mut_range = linear_seq.range_mut(0, 111).unwrap(); for e in mut_range { println!("{e}"); } } 이 코드는 0에서 110까지의 요소를 인쇄합니다. 아웃로덕션: 이 글을 끝까지 읽어주셔서 감사드리며, 이 글에서 유용한 내용을 찾으셨기를 바랍니다. 이 라이브러리를 개선할 수 있는 제안 사항이 있으면 , 싶다면 정말 좋을 것입니다. GitHub에서 문제를 공개하고 라이브러리에 기여하고 게시됨 여기에도