• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 394
  • Last Modified:

CLIST Finding Element !

hi guys,

Sorry need some conceptual help. I guess it might be some fundamental misconception i have here. Have been trying to do such a simple program for the whold day today. Decided to post here for an advise to speed up my process.

I'm writting a simple function that reads in a list of say 4 characters and each carry a certain weight. For each character read in, I will check with this list and if the same character exists, it will update the new weight of this character. If it does not, it will create a new entry. Eventually, i will need to sort them by the final computed weight values of the characters.

What i did was simply as followed:

typedef struct {
      char character;
      float weight;
} characterIndex;

typedef CList<characterIndex, characterIndex> characterTable;

void computeBest() //determine best result;
{
                //inpt string where character is derived from
                //assumed they have been initialised to few string datas..
                CString headab,headab2,headab3,headab4;
             
      characterTable cTable;
               
      float ab = 1.0;
      float cb = 0.9;
      float ab2 = 0.8;
      float cb2 = 0.7;

      //adding to character table assigning to appropriate weight
      
      characterIndex entry1,entry2,entry3,entry4;

      entry1.character=headab.GetAt(0);
      entry1.weight=ab;
      
      cTable.AddHead(entry1);
   
      cTable.Find(headab2.GetAt(0));.....

** My qn here is how do i find the object which carries the character I wish to find from the CLIST ?
My above method gave me error. =( Cos in the first place, it is supposed to feed in the object characterIndex i created..but the thing is i wish to find this characterIndex.character from the list...

Please advise me if it is possible and what is the likely approach i should take? Thanks so much again!




0
ricola
Asked:
ricola
  • 4
  • 3
1 Solution
 
ricolaAuthor Commented:
any kind help here ? increasing points due to urgent need to solve the problem.
0
 
ricolaAuthor Commented:
My main question to the long qn i typed above is :

How do i make use of Find( object) in CLIST where what I want is not to search that particular object but more of one of the atttribute of the object element say my object is declared by a STRUCT.

thanks.
0
 
mactep13Commented:
Here is a loop to go through to find the object:

CList<SomeStruct, SomeStruct> list;

 SomeStruct myStruct
for (int idx = 0; idx < list.GetSize(); idx++)
{
             if (list.GetAt(idx).MyElementOfStruct == ElementINeed2Find)
             {
                     // do whatever with this struct
                     myStruct = list.GetAt(idx);
                     break;
             }
}
MyStruct must have both a copy constructor and an overloaded assignment operator for this to work, UNLESS, the struct contains only native data types such as int, char, double, long, etc. Anything complex, you will need to let the compiler know how to handle. Another words, if you have a struct inside a struct, then the compiler needs to know how to copy this struct from one object to another. Here is an example:

struct NestedStruct
{
  int xx;
char yy;
};
struct SomeStruct
{
  int x;
char y[10];
NestedStruct nested;

// Here is the assignment operator...
SomeStruct& operator=(const SomeStruct& st)
{
   x = st.x;
   strcpy(y, st.y);
// this is where you tell compiler how to handle nested struct
   nested.xx = st.nersted.xx;
   nested.yy = st.nested.yy;
   return *this;
}
};

The copy constructor follows the same form but does not return *this;
SomeStruct::SomeStruct(const SomeStruct& st)
{

// same code as = operator here without return
}

Hope this helps.

Mactep.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
ricolaAuthor Commented:
hi tks!

your code reminded me how stupid i am! =b guess i was so dependent on the implemented methods that i forgot that i can actually loop through the list and retrieve the indiduval objects and get the particular attribute i wish from that object!

i dont have any of those constructors and overloading etc and as what you said, my stuct is just combination of char and float data type.  And yah, your code sparks my mind on how i shld 'viewed' my coding =b

keep ya updated. tks again
0
 
mactep13Commented:
Actually with a CLIst, you need something like this:

POSITION pos = myList.GetHeadPosition();
while(NULL != pos)
{
    CMyElement element = myList.GetNext(pos);
    if (element.attribToSearch == WhatIAmLooking4)
    {
           // DO whatever
          break;
    }
}

This is somewhat different from CArray example I gave earlier. The list does not have indexes, only position. By getting the position with GetHeadPosition, you get the pointer to head. If its null, you're done - list is empty. Otherwise, loop through by calling GetNext. GetNext will update the position for you. It takes a POSITION& as an arg. Do NOT update the position yourself (by calling pos++ or pos--) It WILL NOT work.

Hope this helps.

Mactep.
0
 
ricolaAuthor Commented:
Hi Mactep

Thanks for the advice. I heeded tat. But apparently the program just keep having an debug assertion error at afxtempl.h!
When RemoveAt(pos) is executed, it just failed cos the messagebox before it appears =(

Argh. Kill me.

            POSITION pos = cTable.GetHeadPosition();
            while(pos != NULL)
            {
                  entry = cTable.GetNext(pos);
                  if (entry.character == input[i]){
                        entry.weight = entry.weight + weight[i];
                        cTable.AddTail(entry);
                        AfxMessageBox("after adding");
                        cTable.RemoveAt(pos);      
                  }

                  else {
                  //not in table, add entry in
                  characterIndex entry;
                  entry.character=input[i];
                  entry.weight=weight[i];
                                                cTable.AddTail(entry);
                  }

            }//end of while
0
 
mactep13Commented:
Well, first thing is first. The CList you have (as far as I can remember) is not a const. Therefore GetNext() return ELEMENT&, not ELEMENT. Hence, any modification made to the entry will be done to the entry inside the list. You do not need to call AddTail and RemoveAT(). If you modify entry, then it will be ok. At least that is what MSDN says. I havn't played with CLIst in ages :)

Also, I noticed you are trying to add the element if not found...
Here is a bug...    You are adding the element after the first check. I believe what you want to do is to loop through the whole thing and then, IF you did not find any matching elements, insert a new one. You can find out that you went through the whole loop and not found anything in two ways. First, if you find an element, break!!! then after the loop, check for pos. If it is not NULL, you executed a break and hence found you element, otherwise you did not and insert it:

while(pos)
{
      element = list.GetNext(pos);
      if (element.type== whatINeed)
      {
             // do whatever
             break;
      }
}

if (!pos)
{
    // element not found
     list.AddTail(whatever);
}

There is a slight bug in this code. Can you guess what it is???

Yep, if the matching element is the last one, then the pos will be NULL, no matter what. You can hack it by se two lines of code in the if check inside the loop:
 if(!pos)
{
    pos = list.GetHeadPosition();
    break;
}

You're breaking out anyways, so setting the pos to something other then NULL is OK. You need this when you run your check later.

Second method is to create a bool bFound. Set it to false outside of the loop at the top. Then, if found
if (entry.type == whatINeed)
{
         bFound = true;
}

Then check for it AFTER the loop and if it is still false, add tail.
As far as your debug assertion, yep, your code will do it! The problem is that once you called the GetNext, the pos got updated with the next element. That is fine, but if you get to the end, the pos is NULL, and RemoveAt(NULL) WILL cause an ASSERT failure... better believe it :)
Like I said, the code to add tail and RemoveAt is NOT necessary if your list is not a const! I do not believe it is, so the function you're going to call on it looks like this:

ARG_ELEMENT & CList::GetNext(POSITION& pos);

Not:

ARG_ELEMENT CList::GetNext(POSITION& pos) const;

As such, you are given a reference to the element in the return, not a copy of the element. I assume you understand what references are...   And how to use them :)

Hope this helps,

Mactep.

0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now