Link to home
Create AccountLog in
Avatar of rizel
rizelFlag for Japan

asked on

unique arrays within an array

i am trying to store numbers in a 'child' array then store the array in a 'parent' array.  each 'child' array holds numbers in total between 90 and 100. once a number has selected, it cannot be used again in other arrays.
when done, compare arrays in the 'parent' array and find which array has highest total.

example:

array 1    array 2    etc...

97             23
 1              61
                  7

array 1,2, etc will be stored in 'parent' array

--------
problem:

i tried to use a hashtable 'ht' (below) in order to make each 'child' array unique.
'nc' class has 'public int[] number' where numbers are stored.

  // if nc.number is unique
if(!ht.Contains(nc.number)) ht.Add(nc.number);  or
if(ht.Equals(nc.number)) ht.Add(nc.number);

but they didn't work...similar cases for arraylists.

any suggestions? thanks.
Avatar of AlexFM
AlexFM

>> each 'child' array holds numbers in total between 90 and 100.

Does this mean that numbers are restricted and may be from 0 to 100? In this case you can use bool array with initial value false.

bool bNumberUsed[101];    // initial values: all false

bNumberUsed[i] = false, if number i is not used. bNumberUsed[i] = true, if number i is used.

if( ! bNumberUsed[nc.number])
{
    ht.Add(nc.number);  
    bNumberUsed[nc.number] = true;
}
If numbers are not restricted, you need to use some collection. Please show your existing code with HashTable/ArrayList and what errors do you get.
Avatar of rizel

ASKER

oops...
'the number cannot be used again in other arrays.' should be...

'the number cannot be used again in the SAME 'child' array.'
...sorry ;p

------

code snippet of two hashtables being used:

Hashtable ht = new Hashtable; // temp array for nc.number array
Hashtable htc = new Hashtable; // 'parent' array
int aNum = new int[] {1.....99};
numberCollection nc;

...

ht.Clear();
n = ran.Next(aNum.Length);
if(!ht.Contains(n) // unique numbers only
{
      if(total + aNum[n] <= 100) // the total of numbers has to be below or equal 100
      {
            total += aNum[n];
            ht.Add(n, 0);
      }
}
nc = new numberCollection;
ht.Keys.CopyTo(nc.number, 0);

if(!htc.Contains(nc.number)) htc.Add(nc.number);  // store nc into 'parent' array...this one doesn't work
// if(!htc.Equals(nc.number)) htc.Add(nc.number); // ditto

...


class:

public class numberCollection
{
      public int[] number;
}

---------

i dont't get any errors but htc doesn't notice unique nc.number is already in it when there is a 'duplicate' nc.number being created.
This is small test I did which shows that HashTable works as expected:

        static void Main(string[] args)
        {
            Hashtable ht = new Hashtable();

            for ( int i = 0; i < 10; i++ )
                ht.Add(i, 0);

            TestHt(0, ht);
            TestHt(8, ht);
            TestHt(20, ht);
            TestHt(25, ht);
        }

        static void TestHt(int n, Hashtable ht)
        {
            if ( ht.Contains(n) )
                Console.WriteLine(n.ToString() + "  yes");
            else
                Console.WriteLine(n.ToString() + "  no");
        }

Test in debugger why it doesn't work for you. Consider using of bool array instead of HashTable, as described in my first post. To add element i to it, just set array[i] to true. To know whether number exist, test whether array[i] is true. To count total sum, add all indexes of array members which are equal to true.
Avatar of rizel

ASKER

it will work if nc.number IS a single integer but i set nc.number as array of integer (int[] number)

for example, if i want to compare two different arrays by using this:

int[] a = new int[] {1,2,3,4,5};
int[] b = new int[] {1,2,3,4,5};
int[] c = new int[] {2,1,3,4,5};
bool b = false;

if(a == b) b = true;
else b = false;

if(a == c) b = true;
else b = false;

i tried this and the bool results are all false.
is it impossible to compare two different arrays?
Avatar of rizel

ASKER

duh...
typo :p

bool b -> bool bl
Decide where do you use HashTable and where do you use array. It is not clear from your code. You have parent array and child arrays. Which of hem is array and which is HashTable?
Avatar of rizel

ASKER

hashtable, arraylist, array, etc = array ;)

yes you got a point that my code isn't clear.
parent:  hashtable, called 'htc' in my code (ignore 'ht'...it is actually 'htc'...was in a hurry :p  )
child: array of integer (int[]) labeled 'number' in numberCollection class
so, i want to store int[] in a hashtable then compare int[] arrays.  is it clear?

btw, i did use arraylist instead of hashtable, but the results were same.
I suggest you to spend some time for redesign of your program.
Hashtable is not array, this is dictionary which has keys and data. Collection which may be used as array (without size restriction) is ArrayList.
First write child array class (numberCollection). If must keep numbers inside of it (using simple array, or ArrayList, or inverted array). This class must have functions like:

// return true if number is added successfully. false - number already exiast or total is too high
bool Add(int newNumber);
int GetTotal();

Write this class, make simple test for it and ensure it is working properly. After this write parent array class. It must have ArrayList of numberCollection classes. It's methods manipulate with this ArrayList adding new members (child arrays) to it, or calling some methods of numberCollection. For example, this maybe a function which adds number to parent array:

public bool AddNumber(int n)
{
    foreach (numberCollection child in Childs)        // assuming that Childs is ArrayList of numberCollection
    {
        if ( child.Add(n) )
            break;               // exit if added, continue to next child if not added
     }
}

Make clear design and implement it starting from low-level classes (child array) to high level (parent array).
Avatar of rizel

ASKER

i redesigned my program.  it seemed to work alright, but i was surprised it created over 5000
different patterns of numbers under sum of 100.  hopefully, it's not a bad miscalculation.
tested with smaller values and the results
came smaller.

however, according to your last post on 'public bool AddNumber(int n)...'
it won't process if my parent arraylist's child arraylist is empty.
i have to make several child arraylists before giving them new numbers, correct?

-----------

private void collectUniquePatterns()
            {
                  int tnum = int.Parse(this.textBox1.Text); // example: 100
                  ArrayList pal = new ArrayList(); // parent arraylist
                  ArrayList atemp = new ArrayList(); // temp
                  Hashtable ht = new Hashtable(); // store unique numbers only
                  string uniqueString;
                  numberCollection nc;
                  int ncount;
                  int nTries = count = 0;
                  int total;
                  int n;

                  for(;;)
                  {
                        atemp.Clear();
                        ncount = 0;
                        total = 0;
                        uniqueString = String.Empty;
                        do
                        {
                              n = ran.Next(1,tnum);
                              if(total + n < tnum)
                              {
                                    if(!atemp.Contains(n))
                                    {
                                          atemp.Add(n);
                                          total += n;
                                          ncount = 0; // reset
                                    }
                              }
                              else ncount++;
                        } while(ncount < 20);
                        atemp.Sort();
                        foreach(int num in atemp)
                        {
                              uniqueString += String.Format("{0:D2}",num);
                        }

                        // if uniqueString does exist, throw the uniqueString away and try again
                        if(ht.Contains(uniqueString))
                        {
                              nTries++;
                              continue;
                        }

                        ht.Add(uniqueString,0);
                        nc = new numberCollection();
                        nc.uniqueNumber = uniqueString;
                        nc.getTotal = total;
                        nc.al = atemp;
                        pal.Add(nc);
                        count++;
                        if(nTries >= count) break;
                  }
            }

***  class  ***

public class numberCollection
      {
            public ArrayList al;
            public int getTotal;
            public string uniqueNumber;
      }

------------------

what do you think of it?
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Avatar of rizel

ASKER

thanks for your recent post.

i tried your code again and it worked, but several child arraylists have same number collections

what does my parent arraylist do?
it collects child arraylists that contain unique collection of numbers as well as getTotal and
uniqueNumber.  uniqueNumber is like an ID.  getTotal and uniqueNumber are used for other functions.

for example, how many number patterns can be created from 1 to 99 under sum of 100? you get over
52,000 unique patterns (meaning there are over 52,000 child arraylists in the parent arraylist),
and the highest total is 99. (according to my current code--i don't know if the calculation is correct
since over 52,000 patterns from 1 to 99 is pretty bizarre)