Get all possible individual triples using LINQ

I have a list containing these values: {1, 2, 3, 4, 5, 6, 7}. And I want to be able to get a unique combination of three. The result should look like this:

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

I already have 2 for loops that can do this:

for (int first = 0; first < test.Count - 2; first++)
{
  int second = first + 1;
  for (int offset = 1; offset < test.Count; offset++)
  {
    int third = (second + offset)%test.Count;
    if(Math.Abs(first - third) < 2)
      continue;
    List<int> temp = new  List<int>();
    temp .Add(test[first]);
    temp .Add(test[second]);
    temp .Add(test[third]);
    result.Add(temp );
  }
}

But since I am learning LINQ, I am wondering if there is a smarter way to do this?

thank

+4
source share
3 answers

UPDATE: I used this question as the topic for a series of articles starting here ; In this series, I will look at two slightly different algorithms. Thanks for the great question!


, , , , . , , : :

{1, 1, 1 }
{1, 1, 2 }, 
{1, 1, 3 }, 
...
{7, 7, 7}   

, , . 7 x 7 x 7 , , , , , 30 x 30 x 30 x 30 x 30 x 30 x 30 x 30 x 30 30, . .

. -, , . , , , , . , . Add, ; , . .

, 0 31:

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System;

// A super-cheap immutable set of integers from 0 to 31 ; 
// just a convenient wrapper around bit operations on an int.
internal struct BitSet : IEnumerable<int>
{
  public static BitSet Empty { get { return default(BitSet); } }
  private readonly int bits;
  private BitSet(int bits) { this.bits = bits; }
  public bool Contains(int item) 
  {
    Debug.Assert(0 <= item && item <= 31); 
    return (bits & (1 << item)) != 0; 
  }
  public BitSet Add(int item) 
  { 
    Debug.Assert(0 <= item && item <= 31); 
    return new BitSet(this.bits | (1 << item)); 
  }
  public BitSet Remove(int item) 
  { 
    Debug.Assert(0 <= item && item <= 31); 
    return new BitSet(this.bits & ~(1 << item)); 
  }
  IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
  public IEnumerator<int> GetEnumerator()
  {
    for(int item = 0; item < 32; ++item)
      if (this.Contains(item))
        yield return item;
  }
  public override string ToString() 
  {
    return string.Join(",", this);
  }
}

, , . , , . , .

, , , .

. :

  • ? , .
  • , .

.

, , . : , .

, n , n . , , .

, , , , .

, - . , , . , , .

, , , .

static class Extensions
{
  public static IEnumerable<BitSet> Choose(this BitSet b, int choose)
  {
    if (choose < 0) throw new InvalidOperationException();
    if (choose == 0) 
    { 
      // Choosing zero elements from any set gives the empty set.
      yield return BitSet.Empty; 
    }
    else if (b.Count() >= choose) 
    {
      // We are choosing at least one element from a set that has 
      // a first element. Get the first element, and the set
      // lacking the first element.

      int first = b.First();
      BitSet rest = b.Remove(first);
      // These are the permutations that contain the first element:
      foreach(BitSet r in rest.Choose(choose-1))
        yield return r.Add(first);
      // These are the permutations that do not contain the first element:
      foreach(BitSet r in rest.Choose(choose))
        yield return r;
    }
  }
}

, :

class Program
{
  static void Main()
  {
    BitSet b = BitSet.Empty.Add(1).Add(2).Add(3).Add(4).Add(5).Add(6).Add(7);
    foreach(BitSet result in b.Choose(3))
      Console.WriteLine(result);
  }
}

. , . ( , , .) , , , . - , .

+30

:

var data = Enumerable.Range(1, 7);
var r = from a in data
        from b in data
        from c in data
        where a < b && b < c
        select new {a, b, c};
foreach (var x in r) {
    Console.WriteLine("{0} {1} {2}", x.a, x.b, x.c);
}

-

: !

+2
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7 };

var permutations = ints.SelectMany(a => ints.Where(b => (b > a)).
                        SelectMany(b => ints.Where(c => (c > b)).
                        Select(c => new { a = a, b = b, c = c })));
0
source

All Articles