프로그래밍 언어/C#

C# 자료구조 가이드 딕셔너리(Dictionary)와 해시테이블(Hashtable) 사용법 및 장단점

eco7T 2024. 10. 17. 09:51
반응형

C# 프로그래밍에서 딕셔너리(Dictionary)와 해시테이블(Hashtable)의 개념과 차이를 이해하고, 두 자료구조를 효율적으로 사용하는 방법에 대해 설명합니다. 특히, 제네릭(Generic)과 타입 안정성이 중요한 딕셔너리의 사용법을 중심으로, 구체적인 코드 예제와 실습을 통해 자료구조 선택 시 고려해야 할 부분에 대해 설명합니다.

C# 딕셔너리(Dictionary)와 해시테이블(Hashtable)
C# 딕셔너리(Dictionary)와 해시테이블(Hashtable)

 

C# 자료구조 가이드 딕셔너리(Dictionary)와 해시테이블(Hashtable)

  딕셔너리와 해시테이블의 개념 이해

딕셔너리(Dictionary)

딕셔너리는 키와 값을 쌍으로 저장하는 컬렉션(Collection)입니다. 여기서 키(Key)는 각각의 데이터를 식별하는 고유한 값이며, 값(Value)은 해당 키에 연관된 실제 데이터입니다. 예를 들어, 사람의 이름을 키로 하고 나이를 값으로 저장할 수 있습니다. 딕셔너리는 System.Collections.Generic 네임스페이스에 포함되어 있으며, 제네릭 타입을 지원해 키와 값의 타입을 명시할 수 있습니다.

  • 제네릭(Generic): 타입을 일반화하여 다양한 데이터 타입을 사용할 수 있도록 하는 기능.
  • 네임스페이스(Namespace): C#에서 클래스를 그룹화하여 관리하는 방법으로, 이름의 충돌을 방지하기 위해 사용됩니다.
반응형

 

 

해시테이블(Hashtable)

해시테이블은 딕셔너리와 유사하게 키와 값을 쌍으로 저장하는 자료구조입니다. 하지만 딕셔너리와 달리 제네릭을 지원하지 않으며, System.Collections 네임스페이스에 포함됩니다. 해시테이블은 내부적으로 해시 함수(Hash Function)를 사용하여 데이터를 저장하고 검색합니다. 해시 함수는 키를 입력으로 받아서 해당 키가 저장될 위치를 계산하는 함수입니다.

  • 해시 함수: 키를 특정 숫자 값으로 변환하여, 데이터를 저장하거나 찾을 때 사용되는 함수입니다.

 

딕셔너리와 해시테이블의 차이점

  • 제네릭 지원 여부: 딕셔너리는 제네릭을 지원하지만, 해시테이블은 지원하지 않습니다.
  • 타입 안정성: 딕셔너리는 타입이 안전하게 지정되므로, 잘못된 타입의 데이터를 저장할 수 없습니다. 반면, 해시테이블은 객체 타입(Object)을 사용하므로 타입 변환 과정에서 오류가 발생할 수 있습니다.
  • 성능: 딕셔너리는 제네릭 덕분에 해시테이블보다 더 빠르게 작동할 수 있습니다. 이는 캐스팅(casting) 과정이 필요 없기 때문입니다.

 

  딕셔너리의 사용법과 예시

기본 구조 및 선언 방법

딕셔너리를 사용하려면 System.Collections.Generic 네임스페이스를 포함해야 합니다. 선언 시에는 키와 값의 타입을 명시해야 합니다.

using System; using System.Collections.Generic; class Program { static void Main() { // 키는 문자열(string), 값은 정수(int)로 설정된 딕셔너리 선언 Dictionary<string, int> ages = new Dictionary<string, int>(); // 데이터 추가 ages.Add("Alice", 25); ages.Add("Bob", 30); ages["Charlie"] = 35; // Add와 동일하게 작동 // 데이터 검색 int age = ages["Alice"]; Console.WriteLine("Alice의 나이: " + age); // 데이터 삭제 ages.Remove("Bob"); // 모든 데이터 출력 foreach (var pair in ages) { Console.WriteLine(pair.Key + ": " + pair.Value); } } }

 

 

데이터 추가, 검색, 삭제

  • 추가(Add): Add 메서드 또는 대괄호([])를 사용해 키와 값을 추가합니다.
  • 검색: 키를 사용해 값을 검색하며, 해당 키가 존재하지 않을 경우 예외가 발생할 수 있으므로 TryGetValue 메서드를 사용하는 것이 좋습니다.
  • 삭제(Remove): Remove 메서드를 사용해 키에 해당하는 값을 삭제합니다.

실습 예제: 학생 성적 관리 시스템

학생들의 이름과 성적을 관리하는 프로그램을 작성해 봅시다.

using System; using System.Collections.Generic; class Program { static void Main() { Dictionary<string, double> studentGrades = new Dictionary<string, double>(); // 학생 추가 studentGrades.Add("John", 85.5); studentGrades.Add("Emma", 92.3); studentGrades["Liam"] = 78.4; // 특정 학생의 성적 확인 if (studentGrades.TryGetValue("Emma", out double grade)) { Console.WriteLine("Emma의 성적: " + grade); } // 모든 학생의 성적 출력 foreach (var student in studentGrades) { Console.WriteLine(student.Key + ": " + student.Value); } // 학생 삭제 studentGrades.Remove("Liam"); } }

 

 

  해시테이블의 사용법과 예시

기본 구조 및 선언 방법

해시테이블은 System.Collections 네임스페이스를 사용하며, Hashtable 클래스는 키와 값이 모두 객체 타입(Object)으로 저장됩니다.

using System; using System.Collections; class Program { static void Main() { // 해시테이블 선언 Hashtable employees = new Hashtable(); // 데이터 추가 employees.Add("E001", "John"); employees.Add("E002", "Emma"); employees["E003"] = "Liam"; // 데이터 검색 string employeeName = (string)employees["E001"]; Console.WriteLine("E001의 이름: " + employeeName); // 데이터 삭제 employees.Remove("E002"); // 모든 데이터 출력 foreach (DictionaryEntry entry in employees) { Console.WriteLine(entry.Key + ": " + entry.Value); } } }

 

 

실습 예제: 직원 정보 관리 시스템

직원 ID와 이름을 관리하는 프로그램을 작성해 봅시다.

using System; using System.Collections; class Program { static void Main() { Hashtable employeeData = new Hashtable(); // 직원 추가 employeeData.Add("1001", "John Doe"); employeeData.Add("1002", "Jane Smith"); employeeData["1003"] = "Emma Brown"; // 특정 직원의 정보 확인 if (employeeData.ContainsKey("1002")) { Console.WriteLine("1002의 이름: " + employeeData["1002"]); } // 모든 직원 정보 출력 foreach (DictionaryEntry employee in employeeData) { Console.WriteLine(employee.Key + ": " + employee.Value); } // 직원 삭제 employeeData.Remove("1001"); } }

 

 

  딕셔너리와 해시테이블의 성능 비교

메모리 사용량

  • 딕셔너리는 제네릭 타입이기 때문에 데이터 타입이 고정되어 있어 메모리 사용이 효율적입니다.
  • 해시테이블은 객체 타입을 사용하여 데이터를 저장하므로, 데이터를 추가할 때마다 박싱(Boxing)과 언박싱(Unboxing) 작업이 발생해 메모리 사용량이 증가할 수 있습니다.

검색 및 삽입 성능 비교

  • 딕셔너리는 검색과 삽입에서 일반적으로 더 나은 성능을 보입니다. 이는 제네릭 타입 덕분에 형변환이 필요 없기 때문입니다.
  • 해시테이블은 비교적 더 많은 시간이 소요될 수 있으며, 특히 데이터가 많아질수록 성능 차이가 더 두드러집니다.

언제 딕셔너리를 사용하고 언제 해시테이블을 사용하는 것이 좋은가?

  • 딕셔너리는 타입 안정성을 유지하며 더 빠른 성능을 제공하므로, 일반적으로 새로운 프로젝트에서는 딕셔너리를 사용하는 것이 좋습니다.
  • 해시테이블은 구형 코드나 특정 레거시 시스템과의 호환이 필요할 때 사용될 수 있습니다. 그러나 현대적인 C# 개발에서는 딕셔너리가 더 자주 사용됩니다.
반응형