As has been pointed out, the array is sorted. If that's true, and not just a coincidence... (This assumes a /0 terminated string)
TCHAR findfirstuniquechar_sorted (TCHAR *sz)
{
if (!sz) return 0;
// loop through while safe
for (int n = 0; sz \[n\]; n++)
{
if (sz \[n\] == sz \[n+1\]) // we're the same as the one after
continue;
if ( (n > 0) && (sz \[n\] == sz \[n-1\])) // we're the same as the one before!
continue;
// found one that's different from either side.
return sz \[n\];
}
return 0; // none found.
}
If the string is not sorted, the problem becomes harder. As you use TCHAR, I'm assuming unicode, so you can't just have a 26 array for placement...
TCHAR findfirstuniquechar_unsorted (TCHAR *sz)
{
if (!sz)
return 0;
; This line posts badly - it should be CMap less than TCHAR, TCHAR and, int, int and greater-then CharMap; hope that made sense... pre bug reported.
CMap<TCHAR, TCHAR &, int, int &> CharMap;
int nPos;
int nCharPos;
// One pass through string.
for (nPos = 0; sz \[nPos\]; nPos++)
{
if (CharMap.Lookup (sz \[nPos\], nCharPos))
{
// char already used, so signal is as not-counting-anymore
CharMap \[sz\[nPos\]\] = -1;
}
else
{
// New one!
CharMap \[sz\[nPos\]\] = nPos;
}
}
// Now all chars are account for, look for the char with the lowest <= 0 position.
POSITION pos = CharMap.GetStartPosition ();
nPos = -1;
TCHAR c, cFirst = 0;
while (pos)
{
CharMap.GetNextAssoc (pos, c, nCharPos);
if (nCharPos < 0) // not a unique char.
continue;
if ( (nPos == -1) || (nCharPos < nPos)) // is this the earliest, or the first unique one we've mapped?
{
cFirst = c;
nPos = nCharPos;
}
}
return cFirst; // either first unique, or 0;
}
OK, I've just spent FAR too much time on that. I hope it wasn't homework! Iain.
Plz sir... CPallini CPallini abuz drugz, plz plz help urgent.