|
-
May 2nd, 2012, 03:01 PM
#11
Re: Is there ASCII equivalent of CStringArray?
 Originally Posted by zspirit
Here are some of the functions that I have added to my CStringArrayEx.
The first two functions can be rewritten, without deriving from CStringArray. Not only that, the rewrite would work with the CStringArrayA (if it did exist, and it followed the MFC pattern) as well as CStringArray.
Code:
#include "stdafx.h"
#include <algorithm>
template <typename T>
struct IndexSearcher
{
typedef T CStringType;
T m_srch;
IndexSearcher(const T& srch) : m_srch(srch) { }
bool operator()(const T& s) const
{
T strCur = s;
strCur.TrimRight();
return ( strCur == m_srch );
}
};
template <typename T>
struct CaseFinder
{
typedef T CStringType;
T m_srch;
CaseFinder(const T& srch) : m_srch(srch) { }
bool operator()(const T& s) const
{ return s.CompareNoCase(m_srch) == 0; }
};
template <typename MFCStringArrayType, typename UtilityFn>
int GetIndex(const MFCStringArrayType& arr, UtilityFn fn)
{
INT_PTR nItems = arr.GetCount();
const UtilityFn::CStringType* ptr = std::find_if(arr.GetData(), arr.GetData() + nItems, fn);
int index = (int)std::distance(arr.GetData(), ptr);
if (index >= nItems )
return -1;
return index;
}
int main()
{
CStringArray testa;
testa.Add(CString("abc123"));
testa.Add(CString("xxxxxx"));
int in1 = GetIndex(testa, IndexSearcher<CString>(CString("xxxxxx")));
int in2 = GetIndex(testa, CaseFinder<CString>(CString("xxx1xx")));
/* If CStringArrayA existed, this would (or should) compile:
CStringArrayA testb;
testb.Add(CStringA("abc123"));
testb.Add(CStringA("xxxxxx"));
in1 = GetIndex(testb, IndexSearcher<CStringA>(CStringA("xxxxxx")));
in2 = GetIndex(testb, CaseFinder<CStringA>(CStringA("xxx1xx")));
*/
}
This can be improved by putting the template in a header file and just including the header wherever you want to call GetIndex. Also, a namespace wrapped around it makes it self-contained.
Note that there is only one function, GetIndex, and one set of searcher/index finder classes, and not multiple code copies of such. With your current design, if you were to come up with CStringArrayA, you would need to duplicate the code in both classes. With the above setup, no such duplication occurs if CStringArrayA existed.
In general, your answers (at least the ones I've given) requires the usage of templates as a way to communicate what you want to do given a certain type at compile time.
As to your operator overload of - is concerned, is your CStringArray sorted? If so, that entire code for operator - could have been replaced with std::set_difference(). Right now, your operator - is of n^2 complexity, as you have to potentially go through the list n*n times (where n is the number of items in the list). Imagine if there are 1,000 items -- that's a worst case scenario of 1,000,000 comparisons, add to that, you're comparing strings, which is inherently not efficient. If that array were sorted, then you have set_difference() or equivalent to reduce the complexity.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; May 2nd, 2012 at 08:57 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|