题目
已知火星人使用的运算符号为 #;$
,其与地球人的等价公式如下:
x#y=4*x+3*y+2
x$y=2*x+y+3
其中,x
和 y
是无符号整数。地球人公式按照 C 语言规则进行计算,火星人公式中 #
符优先级高于 $
,相同的运算符按从左到右的顺序运算。
输入
火星人字符串表达式结尾不带回车换行。
输入的字符串说明是字符串为仅有无符号整数和操作符组成的计算表达式。
用例保证字符串中操作数与操作符之间没有任何分隔符,用例保证操作数取值范围为 32 位无符号整数,保证输入以及计算结果不会出现整型溢出,保证输入的字符串为合法的求值报文。
例如:123#4$5#76$78
,保证不会出现非法的求值报文,例如:#4$5
这种缺少操作数,4$5#
这种缺少操作数,4#$5
这种缺少操作数,4 $5
有空格,3+4-5*6/7
有其他操作符,12345678987654321$54321
32 位整数溢出。
输出
根据火星人字符串输出计算结果,结尾不带回车换行。
#include <stdio.h>
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
class CDecodeMar
{
public:
CDecodeMar(string strCode)
:m_uiStrOut(0),m_strCode(strCode)
{
Decode();
}
unsigned int GetDecode()
{
return m_uiStrOut;
}
protected:
unsigned int GetPreRes(unsigned int uiLeft,unsigned int uiRight)
{
unsigned int uiRet = uiLeft*4 + uiRight* 3 + 2;
return uiRet;
}
unsigned int GetPostRes(unsigned int uiLeft,unsigned int uiRight)
{
unsigned int uiRet = uiLeft*2 + uiRight + 3;
return uiRet;
}
bool Decode()
{
bool bRet(false);
if (DecodePre(m_strCode) && DecodePost(m_strCode))
{
unsigned int uiRet = strtoul(m_strCode.c_str(),NULL,10);
m_uiStrOut = uiRet;
bRet = true;
}
return bRet;
}
bool DecodePre(string &strCode)
{
bool bRet(false);
while (strCode.find("#") != string::npos)
{
unsigned int uiLeft(0);
unsigned int uiRight(0);
size_t sPos = strCode.find("#");
string strLeft = strCode.substr(0,sPos);
string strRight = strCode.c_str() + sPos + 1;
size_t sLPos = strLeft.rfind("$");
if (strLeft.rfind("#") != string::npos && strLeft.rfind("#") > sLPos)
{
sLPos = strLeft.rfind("#");
}
if (sLPos == string::npos)
{
sLPos = 0;
}
else
{
sLPos += 1;
}
uiLeft = strtoul(strLeft.c_str() + sLPos,NULL,10);
strLeft = strLeft.substr(0,sLPos);
char* pEnd = NULL;
uiRight = strtoul(strRight.c_str(),&pEnd,10);
if (pEnd != NULL)
{
strRight = pEnd;
}
char buffer[12];
itoa(GetPreRes(uiLeft,uiRight),buffer,10);
strCode = strLeft + string(buffer) + (strRight.c_str());
}
bRet = true;
return bRet;
}
bool DecodePost(string &strCode)
{
bool bRet(false);
while (strCode.find("$") != string::npos)
{
unsigned int uiLeft(0);
unsigned int uiRight(0);
size_t sPos = strCode.find("$");
string strLeft = strCode.substr(0,sPos);
string strRight = strCode.c_str() + sPos + 1;
size_t sLPos = strLeft.rfind("$");
if (strLeft.rfind("#") != string::npos && strLeft.rfind("#") > sLPos)
{
sLPos = strLeft.rfind("#");
}
if (sLPos == string::npos)
{
sLPos = 0;
}
else
{
sLPos += 1;
}
uiLeft = strtoul(strLeft.c_str() + sLPos,NULL,10);
strLeft = strLeft.substr(0,sLPos);
char *pEnd = NULL;
uiRight = strtoul(strRight.c_str(),&pEnd,10);
if (pEnd != NULL)
{
strRight = pEnd;
}
char buffer[12];
itoa(GetPostRes(uiLeft,uiRight),buffer,10);
strCode = string(buffer) + (strRight.c_str());
}
bRet = true;
return bRet;
}
unsigned int m_uiStrOut;
string m_strCode;
private:
};
int main()
{
CDecodeMar oDecode("7#6$5#12");
cout << oDecode.GetDecode();
return 0;
}