?? 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 + -