A class to represent group data type and how to use it in code






4.50/5 (2 votes)
Nov 29, 2004
3 min read

42434

631
A class to represent group data type and an example code to demonstrate how to use it in code.
Introduction
Unlike other programming languages like Pascal, a group data type does not exist in C#. That is the reason why I decided to write such a class to represent a group type.
Background
The two main basic ideas of group type are:
- The order is not important, therefore the groups {1,2,3} and {3,2,1} are equal, and that is why when handling groups you do not ask about the position of member in a group but just whether the member belongs to group or not.
- Every member of the group is counted only once, and therefore the groups {1,2,3,1,1} and {1,2,3} are equal, and of course, the more conventional display is {1,2,3}.
All the operators about groups are based on these main ideas.
Using the code
The main class is Group
. The public
methods of Group
are:
public Group (params string[] group)
: Constructor.public void update(params string[] group)
: Update the group with new one.public void clear()
: Empty the group.public Group copyto()
: Copy the group to another one.public void print()
: Print the members of the class to consolepublic override string ToString()
: Return the members of the group instring
.public int power()
: Return the size of the group.public bool is_empty()
: Check whether the group is empty.public bool is_exist(s)
: Check whethers
exists in the group.public static Group operator+(Group g, string s)
: Add member to group.public static Group operator+(string s, Group g)
: Add group to member.public static Group operator+(Group g1,Group g2)
: A union operator between two groups.public static Group operator*(Group g1,Group g2)
: An intersection operator between two groups.public static Group operator-(Group g, string s)
: Remove member from group.public static Group operator-(Group g1, Group g2)
: Sub one group from another.public static bool operator<=(Group g1, Group g2)
: Check whetherg1
group is sub group ofg2
or equal tog2
.public static bool operator>=(Group g1, Group g2)
: Check whetherg2
group is sub group ofg1
or equal tog1
.public static bool operator==(Group g1, Group g2)
: Check whetherg1
is equal tog2
.public static bool operator!=(Group g1, Group g2)
: Check whetherg1
is different fromg2
.public static bool operator<(Group g1, Group g2)
: Check whetherg1
is sub group ofg2
but does not equal tog2
.public static bool operator>(Group g1, Group g2)
: Check whetherg2
is sub group ofg1
but does not equal tog1
.public Group[] P()
: Compute all the sub groups of the current group.
The P
method to compute the sub groups of a group is using the stack class which is a private
class of the Group
class and represents a data structure of stack. The public
properties and methods of stack
are:
public int count
: Property to return the size of the stack.
public stack(int sub_group_size)
: Constructor.public void push(int val)
: Push to stack.public int pop()
: Pop from stack.public int scan(int i)
: Return the value in positioni
.public bool is_empty()
: Check whether the stack is empty.
All those methods are simple and trivial, and the code can be found in the source file attached to the document, and that is why I didn’t display the code here except the P
method which computes the sub groups of current group.
The P
method is complex and took me a long time to write. My first thought at writing this method was to use the recursion way, but then I changed my mind and decided to use stack instead, and I think it was a wise choice.
Here is the code for the P
method, and because of its complexity, it is very well documented:
//return all the subgroups of current group
public Group[] P()
{
//hold the sub groups
Group[] temp=new Group[(int)((Math.Pow(2,this.power())-1))];
//hold the positions of the members of each sub group
stack s=new stack(this.power());
int sub_group_size=1; //hold the size of each sub group
int sub_group_counter=0; //hold the index of each sub group
int member_position=0, //hold the value poped up from satck
prev_member_position=-1; //hold the previous value poped up from stack
//loop to control the creation of each group of subgroups
//according to their size
while (sub_group_size<=this.power())
{
//initialize the stack for each size n from 1 ro n
for (int i=1;i<=sub_group_size;i++)
s.push(i);
//the process of building sub groups at each size is continue
//until the stack is empty.
//when the stack is empty it's mean that we finished creating all the
//sub groups of this size.
while (!s.is_empty())
{
temp[sub_group_counter]=new Group();
for (int i=0;i<=s.count-1;i++) //building specific subgroup
temp[sub_group_counter]+=(string)this.group[s.scan(i)-1];
sub_group_counter++;
//after creating each specific sub group we should to drop out
//from stack all the positions that came to end or in a nother word
//finished their job in the most internal loop
do
{
prev_member_position=member_position;
member_position=s.pop();
}
while (member_position>=this.power() ||
prev_member_position==member_position+1);
//if the stack is not empty we should advance the new internal position
//and if necessary also to accomplish new positions instead of the
//positions we droped out
if (member_position!=-1)
{
s.push(++member_position); //advancing the new internal position
//accomplishing the new sub group to the correct size instead
//of the positions we droped out from the stack
for (int i=s.count;i<sub_group_size;i++)
s.push(++member_position);
}
} //end of loop control about the stack emptiness
sub_group_size++;
} //end of loop control about the sub group size
return temp;
}
Here is an example code that demonstrates using the Group
class:
using System;
using Groups;
class main
{
static void Main(string[] args)
{
//this program is coming to demonstrate the use of the Group class.
//the input of the program is lists of words.
//the outputs are:
// 1. all the words in each list (every word is displayed only once).
// 2. all the words exist in each list that don't exist in the other lists.
// 3. all the words of all input lists (every word is displayed only once).
// 4. all the common words which exist
// in all the lists(every word is dispayed once).
// 5. the most representing relation between every pair of lists.
int lists_counter;
Group g=new Group();
System.Console.WriteLine();
num_of_lists:
try
{
System.Console.Write("please insert number of lists: ");
lists_counter=int.Parse(System.Console.ReadLine());
}
catch (Exception)
{
goto num_of_lists;
}
Group[] group=new Group[lists_counter];
for (int i=0;i<=lists_counter-1;i++)
{
System.Console.Write("please insert list" +
"of words with space between them: ");
string s=System.Console.ReadLine();
string[] list=s.Split(' ');
group[i]=new Group(list);
}
//printing the members of every group
System.Console.WriteLine();
System.Console.WriteLine("printing the groups");
System.Console.WriteLine("===================");
for (int i=0;i<=group.Length-1;i++)
group[i].print();
System.Console.WriteLine();
//printing the members of every group which not belong to the other groups
g.clear();
System.Console.WriteLine("printing members of each group" +
" that don't belong to other groups");
System.Console.WriteLine("==============================" +
"===================================");
for (int i=0;i<=group.Length-1;i++)
{
g=group[i].copyto();
for (int j=0;j<=group.Length-1;j++)
if (i!=j) g-=group[j];
g.print();
}
System.Console.WriteLine();
//printing the union of all lists
System.Console.WriteLine("printing the union of all lists");
System.Console.WriteLine("===============================");
g.clear();
for (int i=0;i<=group.Length-1;i++)
g+=group[i];
g.print();
System.Console.WriteLine();
//printing the intersection of all lists
System.Console.WriteLine("printing the intersection of all lists");
System.Console.WriteLine("======================================");
g=group[0];
for (int i=1;i<=group.Length-1;i++)
g*=group[i];
g.print();
System.Console.WriteLine();
//printing the relation between each pair of groups
System.Console.WriteLine("printing the relation between each pair of groups");
System.Console.WriteLine("==================================================");
System.Console.WriteLine();
for (int i=0;i<=group.Length-2;i++)
for (int j=i+1;j<=group.Length-1;j++)
if (i!=j)
{
if (group[i]<group[j])
System.Console.WriteLine("{0} < {1}",group[i],group[j]);
else if (group[i]>group[j])
System.Console.WriteLine("{0} > {1}",group[i],group[j]);
else if (group[i]==group[j])
System.Console.WriteLine("{0} = {1}",group[i],group[j]);
else
System.Console.WriteLine("{0} <> {1}",group[i],group[j]);
}
System.Console.ReadLine();
}
}
Points of Interest
The most challenging part of the code is the P
method. By writing this code, I also learnt how to work with operators overloading, and in this issue, I felt sorry about the absence of the =
operator because I noticed it can't be overloaded.
History
- 26/11/2004 – first version.