数制转换

文件: lib/NumberConvert.hpp
#ifndef NUMBERCONVERT_HPP_
#define NUMBERCONVERT_HPP_
#include <string>
#include <map>
#include <exception>
#include <sstream>

namespace HyertyMath {

/* **** 主类定义 **** */
class NumberConvert
{
public:
	/* **** 嵌套类声明 **** */
	class InvalidBase;  
	class InvalidFormat;
	/* **** 类成员声明 **** */
	// 数字映射表,映射一个char字符和它表示的int权值
	static std::map<char, int> const &digitMap;
	static std::string const charMap;
	// 解码,给定一个数字的字符串字面值形式和其基数base(进制数),解码为一个int值
	static int decode(std::string const &s, int base);
	// 编码,将一个int值,以base为基数,编码为字符串
	static std::string encode(int n, int base);
	// 编码转换,将以fromBase为基的数转换为以toBase为基的形式
	static std::string convert(std::string const &s, int fromBase, int toBase) {
		int n = decode(s, fromBase);
		return encode(n, toBase);
	}
	// 辅助函数
	static void validateBase(int base);  // 效验基(进制)是否合法
	static void validateFormat(std::string const &s, int base);  // 效验输入格式
public:
	NumberConvert(int from=10, int to=10) {
		setFrom(from);
		setTo(to);
	}
	// virtual ~NumberConvert() { }  // DO NOT intend to be a base class
	void setFrom(int from) {
		validateBase(from);
		this->from = from;
	}
	void setTo(int to) {
		validateBase(to);
		this->to = to;
	}
	int decode(std::string const &s) {
		return decode(s, from);
	}
	std::string encode(int n) {
		return encode(n, to);
	}
	std::string convert(std::string const &s) {
		validateFormat(s, from);  // 效验输入格式是否有效
		int n = decode(s);
		return encode(n);
	}
private:
	int from, to;
};

/* **** TODO: 嵌套类定义 **** */
class NumberConvert::InvalidBase: public std::exception {
public:
	InvalidBase(int base) {
		std::stringstream msgBuf;
		msgBuf << "Invalid base: " << base << "!";
		msg = msgBuf.str();
	}
	InvalidBase &operator=(InvalidBase const &e) {
		msg = e.msg;
		return *this;
	}
	~InvalidBase() throw() { }
	char const *what() const throw() {
		return msg.c_str();
	}
private:
	std::string msg;
};

class NumberConvert::InvalidFormat: public std::exception { 
public:
	char const *what() const throw() {
		return "Invalid format!";
	}
};

/* **** 类内联函数定义 **** */
inline void NumberConvert::validateBase(int base) {
	if (base < 2 || base > 36) {
		throw InvalidBase(base);
	}
}

inline void NumberConvert::validateFormat(std::string const &s, int base) {
	std::string::const_iterator iter = s.begin(), end = s.end();
	while(iter != end) {
		std::map<char, int>::const_iterator mIter = digitMap.find(*iter);
		if (mIter == digitMap.end() || mIter->second >= base) {
			throw InvalidFormat();
		}
		++iter;
	}
}

}

#endif /*NUMBERCONVERT_HPP_*/


文件: lib/NumberConvert.cpp
#include "NumberConvert.hpp"
#include <list>

namespace {
	std::map<char ,int> &getDigitMap();
}  // end of anonymous namespace

namespace HyertyMath {
        
    std::map<char, int> const &NumberConvert::digitMap = getDigitMap();
    std::string const NumberConvert::charMap(
    		"0123456789abcdefghigklmnopqrstuvwxyz");
    
    // 解码,给定一个数字的字符串字面值形式和其基数base(进制数),解码为一个int值
    int NumberConvert::decode(std::string const &s, int base) {
    	int n = 0;
    	std::string::const_iterator iter = s.begin(), end = s.end();
    	while(iter != end) {
    		n = n * base + digitMap.find(*iter)->second;
    		++iter;
    	}
    	return n;
    }
    
	// 编码,将一个int值,以base为基数,编码为字符串
	std::string NumberConvert::encode(int n, int base) {
		std::list<char> buf;
		int q, r;
		while(n >= base) {
			q = n / base;
			r = n % base;
			buf.push_front(charMap[r]);
			n = q;
		}
		// 当 n < base 时一定 q = 0, r = n 
		buf.push_front(charMap[n]);
		return std::string(buf.begin(), buf.end());
	}
}

namespace {
    
    // 正常情况下,这个函数只应该在初始化NumberConvert::digitMap时被调用一次
    std::map<char ,int> &getDigitMap() {
    	static std::map<char, int> digitMap;
    	// 首次调用标识,防止意外的多次调用时重复设置digitMap的值
    	static bool firstTime = true;
    	if (!firstTime) {
    		return digitMap;
    	}
    	for(char c = '0'; c <= '9'; ++c) {
    		digitMap[c] = c - '0';
    	}
    	char c1 = 'a', c2 = 'A';
    	for( ; c1 <= 'z' && c2 <= 'Z'; ++c1, ++c2) {
    		digitMap[c1] = c1 - 'a' + 10;
    		digitMap[c2] = c2 - 'A' + 10;
    	}
    	firstTime = false;
    	return digitMap;
    }
    
}  // end of anonymous namespace


文件: main.cpp
#include <iostream>
#include <string>
#include <exception>
#include "lib/NumberConvert.hpp"

int main(int argc, char **argv) {
	std::string s;
	int from, to;
	std::cout << ">>> ";
	while(std::cin >> s >> from >> to) {
		std::string s2;
		try {
			s2 = HyertyMath::NumberConvert(from, to).convert(s);
		}
		catch(std::exception &e) {
			s2 = e.what();
		}
		catch(...) {
			throw;
		}
		std::cout << s2 << "\n>>> ";
	}
	return 0;
}

你可能感兴趣的:(C++,c,C#)