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 console
public override string ToString()
: Return the members of the group in string
.
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 whether s
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 whether g1
group is sub group of g2
or equal to g2
.
public static bool operator>=(Group g1, Group g2)
: Check whether g2
group is sub group of g1
or equal to g1
.
public static bool operator==(Group g1, Group g2)
: Check whether g1
is equal to g2
.
public static bool operator!=(Group g1, Group g2)
: Check whether g1
is different from g2
.
public static bool operator<(Group g1, Group g2)
: Check whether g1
is sub group of g2
but does not equal to g2
.
public static bool operator>(Group g1, Group g2)
: Check whether g2
is sub group of g1
but does not equal to g1
.
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 position i
.
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:
public Group[] P()
{
Group[] temp=new Group[(int)((Math.Pow(2,this.power())-1))];
stack s=new stack(this.power());
int sub_group_size=1;
int sub_group_counter=0;
int member_position=0,
prev_member_position=-1;
while (sub_group_size<=this.power())
{
for (int i=1;i<=sub_group_size;i++)
s.push(i);
while (!s.is_empty())
{
temp[sub_group_counter]=new Group();
for (int i=0;i<=s.count-1;i++)
temp[sub_group_counter]+=(string)this.group[s.scan(i)-1];
sub_group_counter++;
do
{
prev_member_position=member_position;
member_position=s.pop();
}
while (member_position>=this.power() ||
prev_member_position==member_position+1);
if (member_position!=-1)
{
s.push(++member_position);
for (int i=s.count;i<sub_group_size;i++)
s.push(++member_position);
}
}
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)
{
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);
}
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();
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();
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();
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();
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.