-2

In C#,

Given the following array of integers e.g. 100001 100002 100005 100006 100007 100009 100011

I want to produce a data structure holding the following values

[0] => {Type= "Continuous", Count=2, Items = [100001, 100002]}
[1] => {Type= "Continuous", Count=3, Items = [100005, 100006, 100007]}
[2] => {Type= "Individual", Count=2, Items = [100008, 100011]}

The data structure is not important. I am looking for an algorithm to group the integers in this way.

puri
  • 1,829
  • 5
  • 23
  • 42

2 Answers2

0

Given that your array of integers is sorted:

class MyGroup
{
   public string Type => (Numbers?.Count??0) == 1? "Individual" : "Continuous";
   public List<int> Numbers;
   public int Count => Numbers.Count;
}

List<MyGroup> LST = new List<MyGroup>();

List<int> Temp = new List<int>();

//Run from 0 to second-last element (arr is your array)
for (int i = 0; i < arr.Length - 1; i++)
{
  Temp.Add(arr[i]); //add this number to current group's list
  if (arr[i + 1] != arr[i] + 1) //if next number is not adjacent
  {
    LST.Add(new MyGroup() { Numbers = Temp }); //create a new group
    Temp = new List<int>(); //and a new current list
  }
}

LST.Add(new MyGroup() { Numbers = Temp }); //create a new group

//The above loop exits before the last item of the array.
//Here we simply check if it is adjacent, we add it to the last group.
//otherwise we create a new group for it.
if (arr[arr.Length - 1] == arr[arr.Length - 2] + 1)
  LST.Last().Numbers.Add(arr.Last());
else
  LST.Add(new MyGroup() { Numbers = new List<int>(new[] { arr.Last() }) });
dotNET
  • 33,414
  • 24
  • 162
  • 251
  • Is there a way to only group continuous elements if the continuous segment contains over N elements? – puri May 14 '17 at 13:19
  • Yes. In the above code, inside the `for` loop's `if` condition, check if there are over N elements in `Temp`. If so, continue with the current code. Otherwise, run a nested loop within `else`, where u create individual groups for each element of `Temp`. – dotNET May 14 '17 at 13:21
  • Slight mistake on my part. I thought you wanted to keep sparse items individual; i.e. one in each group. You'll need to do minor modification to group sparse items. – dotNET May 14 '17 at 13:23
  • Yes I would like to group sparse items. That is my intention but I didn't specify this in my original question so my mistake. Thanks. – puri May 14 '17 at 13:29
0

Here is a solution:

class Group
{
    public int StartIndex { get; set; }

    public int EndIndex { get; set; }

    public int Length { get { return EndIndex - StartIndex; } }

    public override string ToString()
    {
        return $"{StartIndex}-{EndIndex}";
    }
}

Then

static List<Group> FindGroups(int[] intArray)
{
    List<Group> groups = new List<Group>();
    int tempStartIndex = 0;
    for (int i = 1; i < intArray.Length; i++)
    {
        var value = intArray[i] - intArray[i - 1] == 1 ? 0 : 1;
        if (value == 1)
        {
            groups.Add(new Group() { StartIndex = tempStartIndex, EndIndex = i - 1 });

            tempStartIndex = i;
        }
    }
    if (groups[groups.Count - 1].EndIndex != intArray.Length)
    {
        groups.Add(new Group() { StartIndex = tempStartIndex, EndIndex = intArray.Length - 1 });
    }
    return groups;
}
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116