华为OD机试 火星文计算【C++】

题目 

已知火星人使用的运算符号为 #;$,其与地球人的等价公式如下:

  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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值