// MatchingString.cpp
#include "StdAfx.h"
#include "SmartBuf.h"
#include "MatchingString.h"
int StrTrim0(CONST TCHAR* src, int len, int* start /* = NULL */)
{
int begin = 0;
while( begin < len
&& (' ' == src[begin] || '\t' == src[begin] || '\r' == src[begin] || '\n' == src[begin])
) begin++;
int trim_len;
if(begin == len) {
begin = 0;
trim_len = 0;
}
else {
int end = len - 1;
while( end >=0
&& (' ' == src[end] || '\t' == src[end] || '\r' == src[end] || '\n' == src[end])
) end--;
trim_len = end - begin + 1;
}
if(start)
*start = begin;
return trim_len;
}
TCHAR* StrTrim(TCHAR* dst, CONST TCHAR* src, int len)
{
int start;
int trim_len = StrTrim0(src, len, &start);
memmove(dst, src+start, trim_len*sizeof(TCHAR));
dst[trim_len] = 0;
return dst;
}
TCHAR* StrReplace(TCHAR* tszTarget, int iBufSize, CONST TCHAR* tszRep, CONST TCHAR* tszNew)
{
int iBufChars = iBufSize / sizeof(TCHAR);
ASSERT(AfxIsValidString(tszTarget));
ASSERT(iBufChars>0);
ASSERT(AfxIsValidString(tszRep));
ASSERT(NULL==tszNew || AfxIsValidString(tszNew));
int nTargetLen = _tcslen(tszTarget);
int nRepLen = _tcslen(tszRep);
int nReplacementLen = NULL==tszNew ? 0 : _tcslen(tszNew);
TCHAR* tszStart = tszTarget;
TCHAR* tszFind;
while(NULL != (tszFind = _tcsstr(tszStart, tszRep))) {
int offset = tszFind - tszTarget;
if(nReplacementLen+offset >= iBufChars) { //Buffer 尺寸不够
ASSERT(false);
return NULL;
}
//移动被替换字符串后面的内容
if(nReplacementLen != nRepLen) {
memmove(tszFind + nReplacementLen, tszFind + nRepLen,
(nTargetLen - nRepLen - offset + 1) * sizeof(TCHAR)); //移动时包括结束符
nTargetLen += nReplacementLen - nRepLen;
}
//替换字符串
if(nReplacementLen > 0) {
memcpy(tszFind, tszNew, nReplacementLen * sizeof(TCHAR));
}
tszStart = tszFind + nReplacementLen;
}
return tszTarget;
}
LPTSTR sprintfn(LPTSTR buf, __int64 num, int iNumeralFormat /* = 10 */)
{
*buf = 0;
DWORD dwl = (DWORD)num;
DWORD dwh = *(((DWORD*)&num) + 1);
if(2 == iNumeralFormat) {
*(buf + 64) = 0;
int i = 63;
while(i >= 32) {
*(buf + i--) = TCHAR((dwl&1) + _T('0'));
dwl >>= 1;
}
while(i >= 0) {
*(buf + i--) = TCHAR((dwh&1) + _T('0'));
dwh >>= 1;
}
}
else if(16 == iNumeralFormat) {
_stprintf(buf, _T("%08X%08X"), dwh, dwl);
}
else if(3<=iNumeralFormat && iNumeralFormat<=10) {
bool bNegative;
if(num < 0) {
bNegative = true;
num = -num;
}
else
bNegative = false;
TCHAR tmpBuf[65];
int iBit = 0;
if(0 == num)
*(tmpBuf + iBit++) = _T('0');
else {
while(num) {
int nch = int(num%iNumeralFormat);
*(tmpBuf + iBit++) = TCHAR(nch + _T('0'));
num /= iNumeralFormat;
}
}
int iBit2 = 0;
if(bNegative)
*(buf + iBit2++) = _T('-');
while( iBit > 0 )
*(buf + iBit2++) = *(tmpBuf + --iBit);
*(buf + iBit2) = 0;
}
else {
ASSERT(false);
}
return buf;
}
LPTSTR sprintfnEn(LPTSTR buf,
__int64 num,
int iNumeralFormat /* = 10 */,
int iDigit /* = -1 */,
int iSeparateSize /* = -1 */,
TCHAR Separater /* = _T(',') */
)
{
ASSERT(buf);
sprintfn(buf, num, iNumeralFormat);
if(iDigit > 0 || iSeparateSize > 0) {
TCHAR* p = (_T('-') == buf[0]) ? buf+1 : buf;
int digits = _tcslen(p); //数字位数
//在前面补0
if(iDigit > 0) {
int diff = iDigit - digits;
if(diff > 0) {
int i;
for(i=digits; i>=0; i--)
p[i+diff] = p[i];
for(i=0; i<diff; i++)
p[i] = _T('0');
digits += diff;
}
}
//在数字中间加上逗号分隔符
if(iSeparateSize > 0) {
int separ = (digits-1) / iSeparateSize; //逗号个数
if(separ > 0) {
int i = separ + digits;
int t = 0;
while(i >= 0) {
p[i--] = p[i-separ];
t++;
if(t == iSeparateSize+1) {
p[i--] = Separater;
if(0 == --separ)
break;
t = 1;
}
}
}
}
}
return buf;
}
static const int STACK_SIZE = 64; //预设的编译堆栈尺寸
int FindingString(LPCTSTR lpszSour, LPCTSTR lpszFind, bool bMatchCase /* = true */, int nSourLen /* = -1 */, int nFindLen /* = -1 */)
{
ASSERT(AfxIsValidString(lpszSour) && AfxIsValidString(lpszFind));
if(-1 == nSourLen)
nSourLen = _tcslen(lpszSour);
if(-1 == nFindLen)
nFindLen = _tcslen(lpszFind);
int m = nSourLen;
int n = nFindLen;
ASSERT(m>0 && n>=0);
if(n > m)
return -1;
else if(n == 0)
return 0;
CSmartBuf<int, STACK_SIZE> SmartBuf(n);
if(!SmartBuf.IsValid())
return -1;
int* next = SmartBuf.Get();
//KMP算法
//得到查找字符串的next数组
{ n--;
int j = 0;
int k = -1;
next[0] = -1;
while(j < n) {
//if(k == -1 || lpszFind[k] == _T('?') || IsEqualChar(lpszFind[j], lpszFind[k], bMatchCase))
//if(k == -1 || lpszFind[k] == _T('?') || lpszFind[j] == _T('?') || IsEqualChar(lpszFind[j], lpszFind[k], bMatchCase))
if(k == -1 || lpszFind[k] == _T('?') || lpszFind[j] == _T('?')
||
( lpszFind[k]==_T('#')
? IsNum(lpszFind[j])
: ( lpszFind[j]==_T('#')
? IsNum(lpszFind[k])
: IsEqualChar(lpszFind[j], lpszFind[k], bMatchCase)
)
)
) {
j++;
k++;
next[j] = k;
}
else
k = next[k];
}
n++;
}
int i = 0;
int j = 0;
while(i < m && j < n) {
//if(j == -1 || lpszFind[j] == _T('?') || IsEqualChar(lpszSour[i], lpszFind[j], bMatchCase))
if(j == -1 || lpszFind[j] == _T('?')
||
( lpszFind[j]==_T('#')
? IsNum(lpszSour[i])
: IsEqualChar(lpszSour[i], lpszFind[j], bMatchCase)
)
) {
i++;
j++;
}
else
j = next[j];
}
return j>=n ? i-n : -1;
}
bool MatchingString(LPCTSTR lpszSour, LPCTSTR lpszMatch, bool bMatchCase /* = true */)
{
ASSERT(AfxIsValidString(lpszSour) && AfxIsValidString(lpszMatch));
if(lpszMatch[0] == 0)//Is a empty string
return (lpszSour[0] == 0);
int nSourceLen = _tcslen(lpszSour);
bool bMatched = true; //匹配指示变量
int nIndexMatch = 0; //匹配下标
int nIndexSour = 0; //...
//开始进行匹配检查
while(lpszMatch[nIndexMatch] != _T('\0')) {
if(lpszMatch[nIndexMatch] == _T('*')) {
while(lpszMatch[nIndexMatch+1] == _T('*'))
nIndexMatch++;
if(lpszMatch[nIndexMatch+1] == 0) {
//lpszMatch[nIndexMatch]是最后一个字符
//bMatched = true;
break;
}
else {
//lpszMatch[nIndexMatch+1]是_T('?')或普通字符
int nSubIndex = nIndexMatch+1;
while(lpszMatch[nSubIndex] != _T('*') && lpszMatch[nSubIndex])
nSubIndex++;
if((nSourceLen-nIndexSour) < (nSubIndex-nIndexMatch-1)) {
//源字符串剩下的长度小于匹配串剩下要求长度
bMatched = false;
break;
}
if(!lpszMatch[nSubIndex]) { //nSubIndex is point to ender of 'lpszMatch'
//检查剩下部分字符是否一一匹配
nSubIndex--;
int nTempIndex = nSourceLen-1;
//从后向前进行匹配
while(lpszMatch[nSubIndex] != _T('*')) {
if( lpszMatch[nSubIndex] == _T('?')
|| (lpszMatch[nSubIndex]==_T('#')
? IsNum(lpszSour[nTempIndex])
: IsEqualChar(lpszMatch[nSubIndex], lpszSour[nTempIndex], bMatchCase)
)
) {
nSubIndex--;
nTempIndex--;
}
else {
bMatched = false;
break;
}
}
break;
}
else { //lpszMatch[nSubIndex] == _T('*')
nSubIndex -= nIndexMatch+1;
int nPos = ::FindingString( lpszSour+nIndexSour,
lpszMatch+nIndexMatch+1,
bMatchCase,
nSourceLen-nIndexSour,
nSubIndex );
if(nPos != -1) { //在'lpszSour+nIndexSour'中找到szTempFinder
nIndexMatch += nSubIndex;
nIndexSour += (nPos+nSubIndex-1);
}
else {
bMatched = false;
break;
}
}
}
} //end of "if(lpszMatch[nIndexMatch] =
c++模板
需积分: 0 167 浏览量
更新于2008-04-04
收藏 25KB RAR 举报
C++模板是C++语言中的一个强大特性,它允许我们编写通用代码,可以在不同数据类型上重复使用。模板可以分为两种主要类型:函数模板和类模板。在这篇文章中,我们将深入探讨C++模板的实现机制、用途以及如何通过示例代码进行实际应用。
1. **函数模板**
函数模板是用于创建泛型函数的蓝图,它允许我们在不指定具体数据类型的情况下编写函数。函数模板定义了一组通用的操作,这些操作可以应用于不同的数据类型。例如,我们可以定义一个名为`swap`的通用交换函数,如下所示:
```cpp
template<typename T>
void swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
```
在这个例子中,`T`是一个类型参数,代表任何数据类型。当我们调用`swap(int x, int y)`或`swap(string s1, string s2)`时,编译器会自动生成特定类型的`swap`函数。
2. **类模板**
类模板类似于函数模板,但它们用于创建泛型类。类模板定义了一个通用的类结构,可以针对多种数据类型实例化。例如,C++标准库中的`std::vector`就是一个类模板:
```cpp
template<typename T, typename Allocator = std::allocator<T>>
class vector {
// ...
};
```
在这里,`T`是元素的类型,`Allocator`是可选的内存分配器类型。我们可以实例化`std::vector<int>`或`std::vector<string>`等。
3. **模板特化**
有时候,对于某些特定的数据类型,我们可能想要为模板提供不同的实现。这时,我们可以使用模板特化。例如,对于`swap`函数,如果我们想要在`std::string`类型上优化性能,可以这样做:
```cpp
template<>
void swap(std::string& a, std::string& b) {
a.swap(b);
}
```
4. **模板元编程**
模板元编程是一种在编译时进行计算的技术,利用模板和类型系统来实现类似函数式编程的抽象。例如,我们可以创建一个计算类型大小的模板:
```cpp
template<typename T>
struct TypeSize {
static const size_t value = sizeof(T);
};
```
5. **模板推断**
模板推断是编译器根据函数调用或类实例化自动确定模板参数的过程。例如,当我们调用`swap(1, 2)`时,编译器会推断出`T`为`int`。
6. **C++标准库中的模板**
C++标准库广泛使用了模板,如`std::vector`、`std::map`、`std::function`等。这些都是通过模板实现的,提供了高度的灵活性和泛用性。
7. **模板的优缺点**
优点:代码复用,提高了效率;无需运行时类型检查,因为类型是在编译时确定的。
缺点:可能会导致编译后的代码膨胀(Oversized binary);编译错误信息可能难以理解。
8. **示例代码分析**
在提供的压缩包文件中,`test.cpp`可能是包含C++模板使用示例的源代码文件。`test.dsp`和`test.dsw`是Visual Studio项目文件,用于管理和构建C++项目。`StdAfx.h`通常包含预编译头文件,用于提高大型项目构建速度。`Smart`可能是某种智能指针或泛型类的实现,利用了C++模板技术。
通过学习和实践C++模板,开发者可以编写更加灵活和高效的代码,适应不同的数据类型和场景。在实际项目中,合理使用模板能够显著提升代码质量,但同时需要注意避免过度使用导致的复杂性和维护难题。

PRETTY2005678
- 粉丝: 0
最新资源
- 区域科技成果转化服务新模式提升园区运营效能.docx
- 【coze智能体开发】coze天气查询机器人模板
- 高校成果转化困局如何破?生态赋能是关键.docx
- 高校院所科技成果转化数智服务平台:技术经理人的高效利器.docx
- 高校院所科技成果转化数智服务平台:构建资源协同新生态.docx
- 高校院所科技成果转化数智服务平台:技术经理人的创新引擎.docx
- 高校院所科技成果转化数智服务平台建设方案建议.docx
- 高校院所科技成果转化数智服务平台建设分析.docx
- 高校院所科技成果转化数智服务平台现状分析及模式创新建议.docx
- 构建高校科技成果转化新生态.docx
- 构建高校院所科技成果转化新生态的数智服务平台.docx
- 关于提升高校院所科技成果转化效能的分析与路径探讨.docx
- 技术成果转化新引擎:数智平台的创新实践.docx
- 科技成果转化服务新模式赋能技术经理人.docx
- 科技成果转化困局与生态协同破局之道.docx
- 科技成果转化效率瓶颈突破之道.docx