📄 gisexpression.cpp
字号:
//gisExpression.cpp
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include "gisExpression.h"
#include "tstack.h"
#include "stod.h"
////////////////////////////////////////////////////////////////////////////
// CSegment
CSegment::CSegment()
{
lstrcpy(name, _T(""));
}
CSegment::CSegment(const TCHAR* str)
{
if(str != NULL)
lstrcpy(name, str);
}
CSegment::CSegment(const CSegment& rg)
{
lstrcpy(name, rg.name);
}
CSegment& CSegment::operator=(const CSegment& rg)
{
if(this == &rg)
return *this;
lstrcpy(name, rg.name);
return *this;
}
////////////////////////////////////////////////////////////////////////////
// CGisExpression
const TCHAR CGisExpression::SEPARATOR = _T('#');
const TCHAR CGisExpression::TEMP_VAR_HEAD = _T('_');
CGisExpression::CGisExpression(BOOL bPostfix/*=FALSE*/)
: m_pExp(NULL), m_iOperator(0), m_bPostfix(bPostfix)
{
m_varList.clear();
m_postfix.clear();
//生成随机数种子
srand((unsigned int)time(NULL));
}
CGisExpression::CGisExpression(const TCHAR* szExp, BOOL bPostfix/*=FALSE*/)
{
m_varList.clear();
m_postfix.clear();
m_pExp = NULL;
m_pExp = new TCHAR[lstrlen(szExp) + 1];
assert(m_pExp != NULL);
m_bPostfix = bPostfix;
lstrcpy(m_pExp, szExp);
SetPRI();
//生成随机数种子
srand((unsigned int)time(NULL));
}
CGisExpression::CGisExpression(const CGisExpression& exp)
{
m_pExp = NULL;
m_pExp = new TCHAR[lstrlen(exp.m_pExp) + 1];
assert(m_pExp != NULL);
lstrcpy(m_pExp, exp.m_pExp);
m_iOperator = exp.m_iOperator;
for(int i = 0; i < m_iOperator; i++)
{
m_pPri[i] = exp.m_pPri[i];
}
m_bPostfix = exp.m_bPostfix;
m_varList = exp.m_varList;
m_postfix = exp.m_postfix;
//生成随机数种子
srand((unsigned int)time(NULL));
}
CGisExpression::~CGisExpression()
{
Free();
}
//operator
CGisExpression& CGisExpression::operator =(const CGisExpression& right)
{
if(this == &right)
return *this;
Free();
m_pExp = new TCHAR[lstrlen(right.m_pExp) + 1];
assert(m_pExp != NULL);
lstrcpy(m_pExp, right.m_pExp);
m_iOperator = right.m_iOperator;
for(int i = 0; i < m_iOperator; i++)
{
m_pPri[i] = right.m_pPri[i];
}
m_bPostfix = right.m_bPostfix;
m_varList = right.m_varList;
m_postfix = right.m_postfix;
return *this;
}
CGisExpression& CGisExpression::operator =(const TCHAR* szExp)
{
Free();
m_pExp = new TCHAR[lstrlen(szExp) + 1];
assert(m_pExp != NULL);
lstrcpy(m_pExp, szExp);
SetPRI();
m_bPostfix = FALSE;//
return *this;
}
// functions
void CGisExpression::Free()
{
m_varList.clear();
m_postfix.clear();
delete m_pExp;
m_pExp = NULL;
}
/*
设置表达式
*/
void CGisExpression::SetExpression(const TCHAR* szExp, BOOL bPostfix/*=FALSE*/)
{
m_bPostfix = bPostfix;
if(szExp != NULL)
{
SetPRI();
Free();
m_pExp = new TCHAR[lstrlen(szExp) + 1];
assert(m_pExp != NULL);
lstrcpy(m_pExp, szExp);
}
}
/*
添加变量
返回值:
0 - 成功
-1 - 已经存在此变量
*/
int CGisExpression::AddVar(const CVarType& var)
{
if(FindVar(var.name) >= 0)
return -1;
m_varList.push_back(var);
return 0;
}
/*
向表达式添加变量 - 如果有重复的变量则跳过
返回值:
0 - 成功
*/
int CGisExpression::AddVar(CVarType* pVarList, int iCnt/*=1*/)
{
assert(pVarList != NULL);
for(int i = 0; i < iCnt; i++)
{
if(FindVar(pVarList[i].name) < 0)
m_varList.push_back(pVarList[i]);
}
return 0;
}
/*
设置变量
非0 - 成功
*/
BOOL CGisExpression::SetVar(const CVarType& vt)
{
BOOL ret = FALSE;
vector<CVarType>::iterator it;
for(it = m_varList.begin(); it != m_varList.end(); it++)
{
if(0 == lstrcmp((*it).name, vt.name))
{
(*it) = vt;
ret = TRUE;
}
}
return ret;
}
/*
取得变量的值
返回值
=0 - 成功
-1 - 变量不存在
*/
int CGisExpression::GetVarValue(const TCHAR* var, double* pRet)
{
assert(pRet != NULL);
//判断是否为数字
if(StringTest(var))
{
*pRet = (double)atod(var, NULL);
}
else//如果不是数字则当作变量,则应在变量列表中去查找变量的值
{
int i = FindVar(var);
if(i < 0)
{
*pRet = 0.0;
return -1;
}
*pRet = m_varList[i].GetValue();
}
return 0;
}
/*
返回值同上GetVarValue
*/
int CGisExpression::SetVarValue(const TCHAR* var, double f)
{
int i = FindVar(var);
if(i < 0)
return -1;
m_varList[i].fValue = f;
m_varList[i].type = VAR_FLOAT;
return 0;
}
/*
删除一个变量
总是返回0
*/
int CGisExpression::DelVar(const TCHAR* var)
{
vector<CVarType>::iterator it;
for(it = m_varList.begin(); it != m_varList.end(); it++)
{
if(0 == lstrcmp((*it).name, var))
m_varList.erase(it);
}
return 0;
}
/*
删除所有变量
返回值:
总是返回0
*/
int CGisExpression::DelAllVar()
{
m_varList.clear();
return 0;
}
/*
查找变量
成功返回索引
失败返回-1
*/
int CGisExpression::FindVar(const TCHAR* var)
{
if(NULL == var)
return -1;
int i = 0;
vector<CVarType>::iterator it;
for(it = m_varList.begin(); it != m_varList.end(); it++, i++)
{
if(0 == lstrcmp((*it).name, var))
return i;
}
return -1;
}
//产生临时变量
/*
临时变量由 ‘__’ + ‘当前的时间(20060407103456008)’ + ‘一个10000以内的随机数构成’,
判断是否为系统临时变量只需要判断变量头两个字符是否全为下画线(_)即可。
显然,用户自定义变量不能以两个下画线打头。
只能生成浮点类型(VAR_FLOAT)的临时变量,已经足够了。
成功返回TRUE;
*/
BOOL CGisExpression::MakeTempVar(CVarType& vartemp)
{
int myTry = 0;
TCHAR buf[MAX_BUF], str[MAX_BUF];
TEMP_VAR_LOOP:
//生成头
buf[0] = buf[1] = TEMP_VAR_HEAD;
buf[2] = _T('\0');
//取得系统时间
SYSTEMTIME st;
GetLocalTime(&st);
wsprintf(str,
_T("%04d%02d%02d%02d%02d%02d%03d"),
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
st.wMilliseconds);
lstrcat(buf, str);
//产生随机数
wsprintf(str, _T("%04d"), rand()%10000);
lstrcat(buf, str);
if(myTry > 5)
return FALSE;
myTry ++;
if(FindVar(buf) >= 0)//已经存在此临时变量,则重新生成
goto TEMP_VAR_LOOP;
//成功生成变量名
vartemp = CVarType(buf, VAR_FLOAT, 0, 0.0);
return TRUE;
}
/*
判断变量是否在变量列表中,并且为临时变量
如果意识条件成立,则返回临时变量在表中的位置
否则返回-1
*/
int CGisExpression::IsTempVar(const TCHAR* var)
{
int ret = -1;
int i = -1;
if((i = FindVar(var)) >= 0)
{
if((var[0] == TEMP_VAR_HEAD) && (var[0] == TEMP_VAR_HEAD))
ret = i;
}
return ret;
}
int CGisExpression::IsTempVar(const CVarType& var)
{
return IsTempVar(var.name);
}
/*
显示表达式
*/
void CGisExpression::ShowExpression(int flag/**/)
{
if(SE_MIDFIX == flag)
{
if(m_pExp != NULL)
puts(m_pExp);
else
puts("<NULL>");
}
else if(SE_POSTFIX == flag)
{
vector<CSegment>::iterator iter;
for(iter = m_postfix.begin(); iter != m_postfix.end(); iter++)
printf("%s ", (*iter).name);
printf("\n");
}
}
/*
VerifyExpression - 检查表达式是否合法
参数:
iPos - [out]返回错误的位置,以0开始
返回值:
0 - 失败
非0 - 成功
*/
int CGisExpression::VerifyExpression(int* pRet/*=NULL*/)
{
if(pRet != NULL)
*pRet = 0;
if(NULL == m_pExp)
return 0;
return 1;
}
/*
MidToPostFis - 中缀式转后缀式
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -