2015-01-19 3 views
1

저는 C#에 익숙하지 않아이 작업을 가지고 있습니다 :실종 된 조합

나는 신원이 확인되지 않은 사람 (예 : 5 명)의 목록을 가지고 있습니다. 이 작업은 목록에있는 사람과 그 사람이 같은 그룹에 속할 수없는 사람들의 그룹을 얻는 것입니다.

EX : 5명

{1}, {2} {3} {4} {5}, {1,3}, {1,4}, {1,5} {2,4}, {2,5}, {3,5}, {1,3,5}

제가 링크 http://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G 에서 결합 방법을 사용하고이 코드가

private void button3_Click(object sender, EventArgs e) 
    { 
     outputBox.Clear(); 
     int nr = Convert.ToInt32(nmbrBox.Value); 
     double tmp = Math.Pow(2, nr); 
     double combs = tmp - 1; 
     List<int> list = new List<int>(); 
     for (int i = 1; i <= nr; i++) 
     { 
      list.Add(i); 
     } 

     outputBox.AppendText(combs.ToString() + " combinari\n\n"); 

     List<string> allCombinations = new List<String>(); 
     for (int i = 1; i <= list.Count; i++) 
     { 
      var combis = new Facet.Combinatorics.Combinations<int>(list, i, Facet.Combinatorics.GenerateOption.WithoutRepetition); 
      allCombinations.AddRange(combis.Select(c => string.Join("", c))); 
     } 

     foreach (var combi in allCombinations) 
     {    
      outputBox.AppendText(combi + "\n"); 
     } 
    } 

내가 원하는 결과 만 표시하도록하려면 어떻게해야합니까?

+1

:

var people = new[] { "Arthur", "Bertha", "Cristobal", "Dolly", "Edouard" }; var indices = Enumerable.Range(0, people.Length); var result = Enumerable .Range(1, people.Length - 1) .SelectMany(i => indices.Combinations(i)) .Where(IsValidCombination) .Select(combination => combination.Select(i => people[i])); 

이것은 다음과 같은 결과를 제공합니다 :이 경우 입력은 이름의 배열은? 적법한 가치를 결정하기 위해 조합을 어떻게 필터링하고 있습니까? – StarPilot

+0

변수를 사용하고 [i + 1] = number [i] +1의 숫자를 확인할 수 있도록 "allCombinations"에서 조합을 가져 오려고했습니다. –

답변

0

나는 솔직한 해결책을 제시 할 수 있습니다. 그것이 그렇게 보이는 것 그래서

public static bool IsGroupValid(string group) 
{ 
    var indexes= group.Split(' ').Select(x=>Int32.Parse(x)).ToList(); 
    for (int i = 0; i < indexes.Count; i++) 
    { 
     if (indexes.Any(x=>x+1==indexes[i])) 
      return false; 
    } 
    return true; 
} 

: 당신이 "1"또는 "1 2"형식 "1 2 3"또는 당신의 group 문자열을 고려, allCombinations에서 foreach는 그룹은 같은 검증 방법을 사용

foreach (var combi in allCombinations) 
{   
    if(IsGroupValid(combi))  
     outputBox.AppendText(combi + "\n"); 
} 
+0

1. 파스 뒤 너무 많은 paranteses (그냥 fyi) 2. 인덱스 허용하지 않습니다 길이 –

+0

매력으로 일했다! 고맙습니다! 짜증나게해서 미안 해요 :) 이제 나는 목록을 공부해야한다는 것을 압니다. –

0

질문은 Windows Forms와 일부 조합 코드의 조합입니다. 제 답변에서 저는 귀하의 질문에 대한 결합 측면에 중점을 둘 것입니다. 당신이 사용하고있는 라이브러리는 매우 좋다고 생각하지만 자기 만의 대답을 만들기 위해서 나는 조합을 생성하기위한 자신의 방법을 만들기로 결정했습니다. 구현은 LINQ와 재귀를 성능에 좋지 않은 방식으로 사용하지만 문제가되지 않는 요소가 너무 많지 않은 한 재귀를 사용합니다.

다음 확장 방법을 사용하는 소정 길이의 원 시퀀스의 조합을 생성하기 위해 (당신은 static class 내부 이것을 넣어야)

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, Int32 count) 
    where T : IComparable<T> { 
    if (count == 1) 
    return source.Select(t => new T[] { t }); 
    return Combinations(source, count - 1) 
    .SelectMany(
     values => source.Where(value => value.CompareTo(values.Last()) > 0), 
     (values, value) => values.Concat(new T[] { value }) 
    ); 
} 

를 입력 [1, 2, 3, 4, 5]이면 count는 4 출력은 [1, 2, 3, 4], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]입니다.

는 조합이 다른 확장 방법은, 시퀀스로부터 튜플을 만드는 데 사용되는 유효한 경우 쉽게 판별 할 수 있도록 상기 입력이 출력 [[1, 2], [2, 4], [4, 5]] 인 다음 [1, 2, 4, 5]이다

public static IEnumerable<Tuple<T, T>> ToTuples<T>(this IEnumerable<T> source) { 
    using (var enumerator = source.GetEnumerator()) { 
    if (!enumerator.MoveNext()) 
     yield break; 
    var lastValue = enumerator.Current; 
    while (enumerator.MoveNext()) { 
     yield return Tuple.Create(lastValue, enumerator.Current); 
     lastValue = enumerator.Current; 
    } 
    } 
} 

경우.

주어진 조합이 유효한지를 결정하기 위해 술어가 사용됩니다. 조합은 그래서 두 consequtive 지수가 적어도 2 일부가 유효 할 수있다 인덱스의 순서로 간주됩니다 :

Boolean IsValidCombination(IEnumerable<Int32> combination) { 
    return combination 
    .ToTuples() 
    .All(tuple => tuple.Item2 - tuple.Item1 > 1); 
} 

지금 당신이 그것을 함께 넣을 수 있습니다. 당신이 시도 무엇

 
Arthur 
Bertha 
Cristobal 
Dolly 
Edouard 
Arthur, Cristobal 
Arthur, Dolly 
Arthur, Edouard 
Bertha, Dolly 
Bertha, Edouard 
Cristobal, Edouard 
Arthur, Cristobal, Edouard 
+0

감사합니다. 나는 그것을 체크 아웃 할 것이다. 나의 방법으로 얻은 문제는 문자열 []에 해답을 저장한다는 사실이다. 그래서 만약 n = 30으로 간다면 1.5Gb 이상으로 RAM을로드하기 시작하여 내 앱이 멈추게됩니다. 그 결과를 발견 한 후 결과를 즉각적으로 보여주는 메소드를 찾아야하므로 메모리가로드되지 않습니다. –

+0

@CroveanVlad : 너무 많은 요소가 있으면 성능 문제로 인해 내 접근 방식이 어려워집니다. 그러나 조합은 즉석에서 생성되므로 매우 높은 CPU 시간 요구 사항으로 인해 거의 모든 메모리가 사용되지 않을 수도 있습니다. n = 30 인 경우 과도한 메모리 나 CPU를 사용하지 않으려면 매우 특정한 알고리즘이 필요합니다. –