HashSet<T>
μμ¦ λ§μ΄ μ¬μ©νκ³ μλ 컬λ μ μΌλ‘ νμ© κ°μΉμ λν΄ κ³΅μ νκ³ μ ν©λλ€.
λ¬Έμ μν©
record Dispatch(string Title, DateOnly From, DateOnly To);
class Assignments
{
// ...
public List<Dispatch> Dispatches{ get; init;} = [];
}
βν견(Dispatch)β μ΄λΌλ λλ©μΈ λ¬Έμ λ "κΈ°κ°μ μ€λ³΅μ΄ λΆκ°νλ€"λ μꡬ μ¬νμ΄ μμ΅λλ€.
List<T> λ μ΄λ¬ν μꡬ μ¬νμ λ§μ‘±νκΈ°μλ λΆμ‘±ν©λλ€. λ§μ½ μ μ½λλ₯Ό κ·Έλλ‘ μ¬μ©νλ€λ©΄, μλμ κ°μ λΆμ°μ€λ° μ½λκ° νλ‘μ νΈ μ¬λ°©μ ν©λΏλ €μ§ κ²μ
λλ€.
void Add(Dispatch dispach, Assignments on)
{
var overlapped = on.Dispatches
.Any(d => !(dispatch.To < d.From || d.To < dispatch.From));
if (!overlapped)
{
on.Dispatches.Add(dispatch);
}
}
ν΄κ²°
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μ μ νν μ μλ μλ¨μ:
- λ³λ μλ£ κ΅¬μ‘° μ μ.
- κΈ°λ³Έ μλ£ κ΅¬μ‘° νμ
μ
λλ€. μ΄ κΈμμλ λλ²μ§Έλ₯Ό μ νν΄μ HashSet<T> μ νμν©λλ€.
class DispatchSet : HashSet<Dispatch>
{
public DispatchSet() : base(
EqualityComparer<Dispatch>.Create(
(x, y) => {
// κ²ΉμΉλ©΄ true, μλλ©΄ false
},
d => 0 // νμ κ°μ ν΄μμ½λ λ°ν
))
{ }
}
λΆλͺ¨μ μμ±μμ "κΈ°κ°μ΄ κ²ΉμΉλ©΄ true λ₯Ό λ°ν"νλ IEqualityComparer<Dispatch> λ₯Ό λ§€κ° λ³μλ‘ λκΈ°λλ‘ μ μνμ΅λλ€.
μ΄ λΉκ΅κΈ°λ
Equals(x, y)μ νΈμΆμ΄ κ°μ λλ κ΅¬μ‘°λ‘ μΌλ°μ μΈ ν΄μμ ( O(1) ) 보λ€λ μ±λ₯ λΉν¨μ¨μ ( O(n) )μ΄κΈ΄ νμ§λ§, μ΄λ βκΈ°κ°μ΄ κ²ΉμΉμ§ μμμΌ νλ€β λ λλ©μΈ μꡬ μ¬νμ μ§ν€κΈ° μν λΉμ©μ λλ€.
μ£Όμμ ꡬνμ λ§€λλ½κ² νκΈ° μν΄, Dispatch μ βλ°μ΄ν° μμ§β λ¬Έμ λ₯Ό λ¨Όμ ν΄κ²°ν©λλ€.
// record Dispatch(string Title, DateOnly From, DateOnly To);
record Dispatch(string Title, DateSpan Span);
record DateSpan(DateOnly From, DateOnly To)
{
// From <= To λ₯Ό κ°μ .
public DateOnly To { get; init; } = From > To ? From : To;
}
static class DateSpanDefaults
{
public static bool Overlapped(this DateSpan a, DateSpan b) =>
!(b.To < a.From || a.To < b.From);
}
μ΄ λ°μμ
μ λ°νμΌλ‘ DispatchSetμ μμ±ν©λλ€.
class DispatchSet()
: HashSet<Dispatch>(EqualityComparer<Dispatch>.Create(
(x, y) => {
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
// κ²ΉμΉλ©΄ true, μλλ©΄ false
return x.Span.Overlapped(y.Span);
}, d => 0));
μ΄ μ»¬λ μ
μ μ±νν Assignments μ
λλ€.
class Assignments
{
// ...
// public List<Dispatch> Dispatches { get; } = [];
// public HashSet<Dispatch> Dispatches { get; } = [];
public DispatchSet Dispatches { get; } = [];
}
μλΉ μ½λλ₯Ό 보μλ©΄,
void Add(Dispatch dispach, Assignments on)
{
// var overlapped = on.Dispatches
// .Any(d => !(dispatch.To < d.From || d.To < dispatch.From));
// if (!overlapped)
// {
// on.Dispatches.Add(dispatch);
// }
if (on.Dispatches.Add(dispatch) is false)
{
MessageBox.Alert("ν견μ κΈ°κ°μ μ€λ³΅λ μ μμ΅λλ€.")
}
}
void AddRange(IEnumerable<Dispatch> dispaches, Assignments on)
{
var addeds = new List<Dispatch>();
var iterations = 0;
foreach(var d in dispatches)
{
if (on.Dispatches.Add(d)) addeds.Add(d);
iterations ++;
}
if (addeds.Count != iterations)
{
var overlaps = iterations - addeds.Count;
var ok = MessageBox.Confirm(
$"μ΄ {iterations} κ° μ€μ, κΈ°κ°μ΄ μ€λ³΅λ " +
$"{overlaps} κ°λ₯Ό λΉΌκ³ μ μ₯ν κΉμ?")
if (!ok) RemoveRange(addeds, on);
}
}
var d1 = new Dispatch("λΆμ° νμ₯", new(new(2026, 1,1), new(2026, 1,10)));
var d2 = new Dispatch("κ΄μ£Ό νμ₯" , new(new(2026, 1,12), new(2026, 1,20)));
var d3 = new Dispatch("μ μ£Όλ νμ₯", new(new(2026, 1,15), new(2026, 1,25)));
DispatchSet dispatches = [d1, d2, d3];
if (dispatches.Count != 3)
{
foreach(var d in new[] {d1, d2, d3}.Except(dispatches))
Console.WriteLine($"λ μ§κ° κ²Ήμ³, {d.Title}μ μ μΈλμμ΅λλ€.");
}
// κ²°κ³Ό
λ μ§κ° κ²Ήμ³, μ μ£Όλ νμ₯μ μ μΈλμμ΅λλ€.
μ½λ© ν¨μ¨μ±
μ¬μ€ HashSet<T>(κ³Ό List<T>)λ νμμ μΌλν΄ λ κ°μ²΄κ° μλκΈ° λλ¬Έμ μΌλ°μ μΌλ‘λ κΆκ³ λμ§ μλ λ°©μμ
λλ€.
νμ§λ§, DispatchSet μ HashSet<T>μ μΈνλΌλ₯Ό μλ¬΄λ° μμ μμ΄ κ·Έλλ‘ μ¬μ©νκ³ μμ΄, μ΄λ° κΆκ³ μ¬νμ μλ°°νλ€κ³ λ³Ό μ μκ³ , μμ μ΄ μκΈ°μ EF Core μ νΈλ컀, System.Text.Json μ§λ ¬ν λꡬ λ±, λ·λ· κΈ°λ° μΈνλΌ νΈνμ±λ μμ°μ€λ½κ² μ μ§λλ μ₯μ μ΄ μμ΅λλ€.
μλ£κ΅¬μ‘°λ₯Ό λ³λλ‘ μ μνλ κ²½μ°, μ΄λ¬ν νΈνμ± λ¬Έμ κΉμ§ κ³ λ €ν΄μΌ ν΄μ, μ λ°μ μΈ μ½λ© ν¨μ¨μ±μ΄ μ’λ€κ³ λ ν μ μμ΅λλ€. (ν ν°λ λ§μ΄ λ€κ² μ£ .)
μ 리νμλ©΄
DispatchSet μ κΈ°κ°μ μ€λ³΅μ νμ©νμ§ μμμΌ νλ λλ©μΈ μꡬ μ¬νμ μΆ©μ‘±νκΈ° μν΄ μ μλμμ΅λλ€.
μ΄ μꡬ μ¬νμ μ’ λ μΌλ°νν΄ λ³΄λ©΄, "μ€λ³΅μ νμ©νμ§ μλ 컬λ μ "μ λν μμλΌκ³ ν μ μλλ°, λ§μ λλ©μΈ λ¬Έμ μμ 곡ν΅μ μΌλ‘ μμ£Ό λ°μνλ νΈμ λλ€.
μ΄λ¬ν μμλ μλμ κ°μ λ¨μΆν μ½λ ν¨ν΄μΌλ‘ μ½κ² ν΄κ²°μ΄ κ°λ₯ν©λλ€.
public class FarSet()
: HashSet<Far>(IEqualityComparer<Far>);