VioletaBabel
4일차 본문
배열
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Program { static void Main(string[] args) { int[] a = new int[5]; for(int i = 0; i < a.Length; ++i) { string s = Console.ReadLine(); a[i] = int.Parse(s); } foreach (int i in a) Console.WriteLine(i); } } | cs |
배열을 초기화하는 세 가지 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Program { static void Main(string[] args) { int[] a = new int[3] { 10, 20, 30 }; foreach (int i in a) Console.WriteLine(i); int[] b = new int[] { 20, 30, 40 }; foreach (int i in b) Console.WriteLine(i); int[] c = { 30, 40, 50 }; foreach (int i in c) Console.WriteLine(i); } } | cs |
Array 클래스의 메소드와 프로퍼티
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | private static bool Checking(int s) {//점수를 비교해 합격을 검사하기 위한 함수 return (s >= 60) ? true : false; } static void Main(string[] args) { int[] score = new int[5] { 89, 59, 68, 90, 84 }; foreach (int i in score)//89 59 68 90 84 Console.WriteLine(i); Console.WriteLine("---"); //int형 배열 정렬. int의 경우 <int>는 없어도 됨. Array.Sort<int>(score); foreach (int i in score)//59 68 84 89 90 Console.WriteLine(i); Console.WriteLine("---"); Console.WriteLine("length : {0} , dimension : {1}", score.Length, score.Rank); Console.WriteLine("---"); //이진 검색 후 해당 값의 인덱스 반환. 해당 값이 없으면 음수 반환. Console.WriteLine("binary\n68 : {0}", Array.BinarySearch<int>(score, 68)); Console.WriteLine("82 : {0}", Array.BinarySearch<int>(score, 82)); Console.WriteLine("---"); //선형 검색 후 해당 값의 인덱스 반환. 해당 값이 없으면 음수 반환. Console.WriteLine("linear\n89 : {0}",Array.IndexOf<int>(score,89)); Console.WriteLine("88 : {0}", Array.IndexOf<int>(score, 88)); Console.WriteLine("---"); //미리 만들어둔 함수의 조건에 배열이 부합하는지를 반환 Console.WriteLine("pass? : {0}", Array.TrueForAll<int>(score, Checking)); ++score[0]; Console.WriteLine("pass? : {0}", Array.TrueForAll<int>(score, Checking)); --score[0]; Console.WriteLine("---"); int a = -1; //원하는 조건의 값이 가장 처음 나오는 인덱스 출력 a = Array.FindIndex<int>(score, Checking); Console.WriteLine(a); // 1이 출력 Console.WriteLine("---"); //배열 크기 재조정 Array.Resize<int>(ref score, 6); foreach (int i in score)//59 68 84 89 90 0 Console.WriteLine(i); Console.WriteLine("---"); //배열 초기화 Array.Clear(score, 1, 2); foreach (int i in score)//59 0 0 89 90 0 Console.WriteLine(i); Console.WriteLine("---"); } | cs |
2차원 배열
1 2 3 | int[,] array = new int[2, 3]; array[1, 2] = 1; //길이가 3인 1차원 배열 2개를 묶은 2차원 배열 | cs |
가변 배열 : 요소로 입력되는 배열의 길이가 모두 같을 필요가 없는 배열.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //가변 배열 선언하기 int[][] j = new int[3][]; j[0] = new int[3] { 1, 2, 3 }; j[1] = new int[2] { 11, 12 }; j[2] = new int[4] { 21, 22, 23, 24 }; int[][] j2 = new int[2][] { new int[] { 31, 32 }, new int[3] { 41, 42, 43 } }; foreach(int[] ar in j) { Console.WriteLine("length : {0}", ar.Length); foreach (int e in ar) Console.Write("{0} ", e); Console.WriteLine(""); } | cs |
//벡터처럼 크기를 줄였다 늘였다 하는 것이 아니라, 하나로 묶인 배열의 길이가 제각각인 배열임을 명심한다.
---
컬렉션 1. ArrayList
배열과 닮았으나 용량을 미리 지정할 필요 없이 자동으로 용량이 늘어나고 줄어드는 컬렉션.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | using System.Collections; // 컬렉션 사용 ArrayList l = new ArrayList(); l.Add(10);//맨 뒤에 값 추가 l.Add(20); l.Add(30); foreach (int i in l) Console.WriteLine(i);//10 20 30 Console.WriteLine("---"); l.RemoveAt(1);//1번 인덱스 삭제 foreach (int i in l) Console.WriteLine(i);//10 30 Console.WriteLine("---"); //1번 자리에 21 값 추가(기존 값들은 1칸씩 뒤로 밀림) l.Insert(1, 21); foreach (int i in l) Console.WriteLine(i);//10 21 30 Console.WriteLine("---"); l.Add(40); l.Add(50); foreach (int i in l) Console.WriteLine(i);//10 21 30 40 50 Console.WriteLine("---"); //범위 값 제거 l.RemoveRange(1, 2); foreach (int i in l) Console.WriteLine(i);//10 40 50 Console.WriteLine("---"); l.Reverse(); //전체 값 뒤집기 foreach (int i in l) Console.WriteLine(i);//50 40 10 Console.WriteLine("---"); l.Sort(); //오름차순 정렬 foreach (int i in l) Console.WriteLine(i);//10 40 50 Console.WriteLine("---"); l.Clear(); //전체 요소 삭제 foreach (int i in l) Console.WriteLine(i);// Console.WriteLine("---"); | cs |
컬렉션 2. Queue
입력은 뒤에서, 출력은 앞에서
1 2 3 4 5 6 7 8 | Queue q = new Queue(); q.Enqueue(1);//큐에 값 넣기 q.Enqueue(2); q.Enqueue(3); q.Enqueue(4); q.Enqueue(5); while (q.Count > 0)//큐에 값 빼기(c++와 달리 값 리턴+값 제거) Console.WriteLine(q.Dequeue());//1 2 3 4 5 | cs |
컬렉션 3. Stack
FILO, LIFO
1 2 3 4 5 6 7 8 | Stack s = new Stack(); s.Push(1);//스택에 값 넣기 s.Push(2); s.Push(3); s.Push(4); s.Push(5); while (s.Count > 0)//스택에 값 빼기 Console.WriteLine(s.Pop());//5 4 3 2 1 | cs |
컬렉션 4. Hashtable
사전과 같은 역할을 함. 키와 값이 쌍으로 이루어짐. 탐색 속도가 빠르고 사용하기 편함.
1 2 3 4 5 6 7 | Hashtable h = new Hashtable(); h["drink"] = "Beer"; h["movie"] = "Dead Poets Society"; h["song"] = "The Moon and Six pence"; Console.WriteLine(h["song"]); Console.WriteLine(h["movie"]); Console.WriteLine(h["drink"]); | cs |
---
Indexer
Index를 통해 객체 내의 데이터에 접근하게 해주는 프로퍼티. 객체를 배열처럼 사용할 수 있게 해줌.
일반적인 프로퍼티와의 차이점은 Index를 이용한다는 점.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Lists { private int[] ar; public Lists() {//생성자 ar = new int[3]; } public int this[int index] // 인덱서 { get { return ar[index]; } set { if(index>=ar.Length) { Array.Resize<int>(ref ar, index + 1); Console.WriteLine("Resized : {0}", ar.Length); } ar[index] = value; } } public int Length { get { return ar.Length; } } //메인에서도 Length를 쓰기 위해 만듦 } static void Main(string[] args) { Lists l = new Lists(); for (int i = 0; i < 5; ++i) l[i] = i; // 배열을 다루듯 인덱스를 통해 데이터 입력 for (int i = 0; i < l.Length; ++i) Console.WriteLine(l[i]); } | cs |
---
제네릭 메소드
제네릭이란 데이터 타입을 일반화하는 것.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | static void CopyArray<T>(T[] source, T[] target) { for (int i = 0; i < source.Length; ++i) target[i] = source[i]; } static void Main(string[] args) { int[] s = { 1, 2, 3, 4, 5 }; int[] t = new int[s.Length]; CopyArray<int>(s, t); foreach (int e in t) Console.WriteLine(e); string[] s2 = { "a", "bb", "c", "dd" }; string[] t2 = new string[s2.Length]; CopyArray<string>(s2, t2); foreach (string e in t2) Console.WriteLine(e); } | cs |
제네릭 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | class Lists<T> { private T[] ar; public Lists() { ar = new T[3]; } public T this[int index] { get { return ar[index]; } set { if(index >= ar.Length) { Array.Resize<T>(ref ar, index + 1); Console.WriteLine("Resized : {0}", ar.Length); } ar[index] = value; } } public int Length { get { return ar.Length; } } } class Program { static void Main(string[] args) { Lists<string> sList = new Lists<string>(); sList[0] = "ab"; sList[1] = "c"; sList[2] = "de"; sList[3] = "f"; sList[4] = "gh"; for (int i = 0; i < sList.Length; ++i) Console.WriteLine(sList[i]); Lists<int> iList = new Lists<int>(); iList[0] = 1; iList[1] = 2; iList[2] = 3; iList[3] = 4; iList[4] = 5; for (int i = 0; i < iList.Length; ++i) Console.WriteLine(iList[i]); } } | cs |
형식 매개 변수 제약걸기
where T : struct //T는 값 형식
where T : class//T는 참조 형식
where T : new() //T는 매개 변수가 없는 생성자 존재
where T : 기반클래스명 //T는 명시한 기반 클래스의 파생 클래스
where T : 인터페이스명 //T는 명시한 인터페이스를 반드시 구현
where T : U //T는 다른 형식의 매개 변수 U로부터 상속받은 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | class StructA<T> where T : struct { public T[] Ar { get; set; } public StructA(int size) { Ar = new T[size]; } } class RefA<T> where T : class { public T[] Ar { get; set; } public RefA(int size) { Ar = new T[size]; } } class Base { } class Derived : Base { } class BaseA<U> where U : Base { public U[] Ar { get; set; } public BaseA(int size) { Ar = new U[size]; } public void CopyArray<T>(T[] Source) where T : U { Source.CopyTo(Ar, 0); } } class Program { public static T CreateIns<T>() where T : new() { return new T(); } static void Main(string[] args) { StructA<int> a = new StructA<int>(3); a.Ar[0] = 0; a.Ar[1] = 1; a.Ar[2] = 2; RefA<StructA<double>> b = new RefA<StructA<double>>(3); b.Ar[0] = new StructA<double>(5); b.Ar[1] = new StructA<double>(10); b.Ar[2] = new StructA<double>(300); BaseA<Base> c = new BaseA<Base>(3); c.Ar[0] = new Base(); c.Ar[1] = new Derived(); c.Ar[2] = CreateIns<Base>(); BaseA<Derived> d = new BaseA<Derived>(3); d.Ar[0] = new Derived(); d.Ar[1] = CreateIns<Derived>(); d.Ar[2] = CreateIns<Derived>(); BaseA<Derived> e = new BaseA<Derived>(3); e.CopyArray<Derived>(d.Ar); } } | cs |
제네릭 컬렉션 1. List<T>
ArrayList와 같은 기능에 사용법도 같으나, ArrayList는 아무 형식이나 넣을 수 있던 점에 반해 형식 매개 변수 T로 입력한 형식 외에는 입력이 불가능한게 차이점이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | List<int> l = new List<int>(); for (int i = 0; i < 5; ++i) l.Add(i); foreach (int e in l) // 0 1 2 3 4 Console.Write("{0} ", e); Console.WriteLine(); l.RemoveAt(2); foreach (int e in l) // 0 1 3 4 Console.Write("{0} ", e); Console.WriteLine(); l.Insert(2, 5); foreach (int e in l) // 0 1 5 3 4 Console.Write("{0} ", e); Console.WriteLine(); | cs |
제네릭 컬렉션 2. Queue<T>
1 2 3 4 5 | Queue<int> q = new Queue<int>(); for (int i = 1; i < 6; ++i) q.Enqueue(i); while (q.Count > 0) // 1 2 3 4 5 Console.WriteLine(q.Dequeue()); | cs |
제네릭 컬렉션 3. Stack<T>
1 2 3 4 5 | Stack<int> s = new Stack<int>(); for (int i = 1; i < 6; ++i) s.Push(i); while (s.Count > 0) // 5 4 3 2 1 Console.WriteLine(s.Pop()); | cs |
제네릭 컬렉션 4. Dictionary<TKey, TValue>
Hashtable의 제네릭 버전
1 2 3 4 5 6 7 | Dictionary<string, string> d = new Dictionary<string, string>(); d["a"] = "apple"; d["b"] = "bag"; d["c"] = "console"; Console.WriteLine(d["c"]); Console.WriteLine(d["b"]); Console.WriteLine(d["a"]); | cs |