728x90
반응형
1. IndexOf, FindIndex, FindAll
using System;
using System.Collections.Generic;
class Program {
public static bool Divide3(int n) { return n % 3 == 0; }
static void Main() {
List<int> c1 = new List<int>() {1, 2, 3, 1, 2, 3, 1, 2, 3, 10};
// 값 검색
Console.WriteLine(c1.IndexOf(3)); // 2
Console.WriteLine(c1.IndexOf(3, 5)); // 5
Console.WriteLine(c1.IndexOf(3, 6, 2)); // -1
// 조건 검색 : 3의 배수 찾기
Console.WriteLine(c1.FindIndex(Divide3)); // 2
Console.WriteLine(c1.FindIndex(n => n % 3 == 0 )); // 2
// 조건을 만족하는 모든 요소 찾기
List<int> c2 = c1.FindAll(n => n % 3 == 0);
foreach(int n in c2)
Console.WriteLine(n);
}
}
① Collections은 다양한 메소드를 제공한다.
=> 요소의 삽입/삭제/열거
=> 선형 검색, 이진검색, 정렬 등의 다양한 알고리즘 제공
다양한 컬렉션의 메소드들에 대한 알아보자.
먼저 11~13번 라인의 IndexOf 이다.
11번 라인과 같이 인자가 1개이면 처음부터 검색해 인자가 있는 위치를 리턴한다.
11번 라인은 3을 찾기 때문에 3번째 위치에 있는 3을 찾아 2를 반환한다. (제로 베이스)
12번 라인과 같이 인자가 2개이면 두 번째 인자의 위치에서 시작해서 첫 번째 인자를 검색한다.
12번 라인은 3을 5번(두 번째 3의 위치)부터 찾는데 5번째가 3이므로 바로 5를 반환한다.
13번 라인과 같이 인자가 3개이면 두 번째 인자의 위치에서 시작해서 첫 번째 인자를 세 번째 인자까지만 검색한다.
13번 라인은 6번(세 번째 1의 위치)부터 3을 찾는데 2칸만 찾는다. 1, 2중에 3을 찾는데 없으므로 -1을 반환한다.
다음은 16~17번 라인의 FindIndex 이다.
FindIndex는 정의로 이동해보면 Predicate<T>라는 bool을 반환하는 delegate를 인자로 받는다.
따라서 사용하려면 delegate를 먼저 정의해야 한다.
여기선 3의 배수를 찾기 위한 Divide3이라는 메소드를 만들어 인자로 전달했다.
따라서 첫 번째 3의 위치인 2를 반환한다.
delegate를 인자로 받으므로 굳이 메소드를 만들 필요없이 람다 표현식으로 처리도 가능하다.
16~17번 라인은 같은 기능을 수행한다.
FindIndex도 IndexOf와 같이 인자의 개수에 따라 옵션을 다르게 줄 수 있는데
특이점은 IndexOf(찾을 것, 시작 위치, 몇 칸) 이라면 FIndIndex(시작 위치, 몇 칸, 메소드) 로 순서가 약간 다르다.
마지막으로 20번 라인의 FindAll이라는 메소드가 있다.
이 메소드도 메소드를 인자로 넘기면 되니 람다 표현식으로도 넘길 수 있다.
조건에 만족하는 모든 요소를 반환하므로 반환 타입은 컬렉션으로 받아야 한다.
② 알고리즘 메소드 사용법
=> 값을 검색하는 메소드
=> 조건자(Predicate)를 사용하는 메소드
=> 조건자 : bool을 반환하는 메소드
2. IComparer<T> interface VS Comparison<T> delegate
using System;
using System.Collections.Generic;
class Program {
static void Main() {
List<int> c = new List<int>() {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
c.Sort();
foreach(int n in c) {
Console.WriteLine(n);
}
}
}
위의 코드는 List의 요소를 오름차순으로 정렬하는 코드이다.
아주 간단한 코드인데 Sort메소드는 오름차순으로만 정렬해주기 때문에
내림차순이라던가, 음수가 껴있는데 절대값으로 바꾸어 정렬한다던가 하는게 불가능하다.
바꾸려면 Sort메소드의 정책을 바꾸어야 한다.
Sort의 정의로 이동해보면 위와 같이 3개의 버전이 있음을 알 수 있다.
Comparsion<T> 와 IComparer<T> 두 개가 있는데 두가지가 뭔지 하나씩 보자.
위와 같이 Comparison은 delegate이고
IComparer은 interface이다.
이제 위의 2개를 이용해 정책을 바꿔보자.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
List<int> c = new List<int>() {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
// Sort(Comparison<T>) : delegate
c.Sort((a, b) => { return a < b ? 1 : ((a == b) ? 0 : -1);});
foreach(int n in c) {
Console.WriteLine(n);
}
}
}
위는 delegate인 Comparison을 이용해 Sort를 내림차순으로 바꾼 코드이다.
메소드를 만들어도 되지만 람다표현식을 이용했다.
using System;
using System.Collections.Generic;
class MyCompare : IComparer<int> {
public int Compare(int a, int b) {
return a < b ? 1 : ((a == b) ? 0 : -1);
}
}
class Program {
static void Main() {
List<int> c = new List<int>() {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
// Sort(IComparer<T>) : interface
c.Sort(new MyCompare());
foreach(int n in c) {
Console.WriteLine(n);
}
}
}
위는 interface인 IComparer을 이용해 Sort를 내림차순으로 바꾼 코드이다.
위와 다르게 Sort의 인자로 메소드가 아닌 객체를 전달했다.
① Sort() 메소드에 비교 정책을 전달하는 방법
728x90
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] 코루틴 (COROUTINE) (2) (0) | 2020.05.05 |
---|---|
[C#] 코루틴 (COROUTINE) (1) (0) | 2020.04.29 |
[C#] 열거자 (Enumerator) (0) | 2020.04.26 |
[C#] Collection과 Interface (0) | 2020.04.26 |
[C#] 컬렉션 (Collection) (0) | 2020.04.23 |