#include "StdAfx.h" #include "AString.h" #include "ListQuene.h" #include "WValList.h" AString::AString(const wchar_t *sw) : SHArray (1) { Clear(); if(sw == NULL) { return; } USES_CONVERSION; *this = W2A(sw); } AString::~AString() { } void AString::Copy(const char *p,long pos) { if(p == NULL) { return; } for(long size = 0; p[size] != NULL; size++); long length1 = pos + size; if(length1 > Length()) { SetLength(length1); } memcpy(pData + pos,p,size*sizeof(char)); } void AString::Copy(long from,long to,long size) { long length1 = to + size; if(length1 > Length()) { SetLength(length1); } char *p1 = pData + from, *p2 = pData + to; if(from > to) { for(long i = 0; i < size; i++) { p2[i] = p1[i]; } } else if(to > from) { for(long i = size - 1; i >= 0; i--) { p2[i] = p1[i]; } } } void AString::MakeUpper() { for(long i = 0; i < Length();i++) { char &c = (*this)[i]; if(c >= 'a' && c <= 'z') { c -= 32; } } } AString& AString::operator << (double d) { AString s; s.Format("%f",d); Copy(s,m_nEnd); long i = m_nEnd - 1; while(pData[i] == '0' && pData[i-1] != '.') { i--; } SetEnd(i + 1); return *this; } AString& AString::Format(const char*format,...) { Clear(); Realloc(1024,false); va_list vlist; va_start(vlist, format); vsprintf(pData, format, vlist); va_end(vlist); m_nEnd = strlen(pData); return *this; } AString& AString::Extract(const char*format,...) { WValList vList(format,*this); char*curP = (char*)(&format) + sizeof(char*); for(vList.MoveToFirst(); !vList.IsOut(); vList.MoveToNext()) { WFormatUnit*p = vList.GetCurData(); switch(p->type) { case WS_CHAR: **((char**)curP) = p->GetAt(0); curP += sizeof(char**); break; case WS_INT: *p >> **((int**)curP); curP += sizeof(int**); break; case WS_DOUBLE: *p >> **((double**)curP); curP += sizeof(double**); break; case WS_STRING: *p >> **((AString**)curP); curP += sizeof(AString**); break; } } return *this; } long AString::ReverseFind(char c) const { for(long i = m_nEnd - 1; i >= 0; i--) { if(pData[i] == c) { return i; } } return NOT_FOUND; } long AString::Find(const AString& s, long from, long to) const { if(s.IsEmpty()) { return NOT_FOUND; } if(to == -1) { to = Length() - 1; } long *next = new long[s.Length()]; s.CreateNextTable(next); for(long i = from, j = 0; i <= to && j < s.Length();) { if(pData[i] == s[j]) { i++; j++; } else { j = next[j]; if(j == -1) { j = 0; i++; } } } delete[] next; if(j == s.Length()) { return i - j; } else { return NOT_FOUND; } } //next(i)=j 当j>0,j为使得p(0)...p(j-1) == p(i-j)...p(i-1)的最大整数; //当j>=0,表示当前被比较字符与当前索引为i的比较字符不相同时,当前比较字符移到j处继续比较; //当j=-1,表示当前被比较字符与当前索引为i的比较字符不相同时, //当前被比较字符前移一位,当前比较字符索引回0,重新比较; void AString::CreateNextTable(long *next) const { if(IsEmpty()) return; next[0] = -1; if(Length() == 1) return; next[1] = 0; long lastIndex = Length() - 1; for(long i = 1,j = 0; i < lastIndex;) { if(pData[i] == pData[j]) { i++; j++; if(pData[i] == pData[j]) next[i] = next[j]; else next[i] = j; } else { j = next[j]; if(j == -1) { j = 0; i++; next[i] = 0; } } } } long AString::Find(const AString&s,SHQuene&quene,long from,long to) const { if(s.IsEmpty()) return NOT_FOUND; if(to == -1) to = Length()-1; long *next = new long[s.Length()]; s.CreateNextTable(next); for(long i = from,j = 0; i <= to;) { if(pData[i] == s[j]) { i++; j++; if(j == s.Length()) { quene.EnQuene(i - j); j = 0; } } else { j = next[j]; if(j == -1) { j = 0; i++; } } } delete[] next; return quene.GetLength(); } long AString::Replace(const AString&s,const AString&d,long from,long to) { if(to == -1) { to = Length()-1; } ListQuenequene; long num = Find(s,quene,from,to); if(num != 0) { long oldLength = Length(); length = oldLength + num * (d.Length() - s.Length()) + 1; char *pTemp = pData; pData = new char[length]; Clear(); long i,j = 0; while(quene.DeQuene(i)) { Copy(pTemp + j, m_nEnd,i - j); *this << d; j = i + s.Length(); } Copy(pTemp + j, m_nEnd, oldLength - j); delete[] pTemp; } return num; } //支持通配符的查找替换 long AString::FindEx(const AString&sFindRule,AString &res,int flag,long from,long to) const { return NOT_FOUND; } void AString::ReplaceEx(const AString&sFindRule,const AString&sReplaceRule,int flag) { } bool AString::Insert(long i,const AString&s) { if(i >= 0 && i <= m_nEnd) { AString temp = Right(m_nEnd - i); SetEnd(i); *this<