如何在c++中定义一个新的数字系统
How to define a new number system in C++
基本上我要做的是在c++中创建一个以62为基数的数字系统(一个字母数字系统——包括a-z, a-z和0-9)。这样的事情是如何完成的呢?我尝试使用这样的字符数组:
const char alphaNum[62] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', ' y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
foobar++;
会简单得多。有没有人有办法定义数字系统,或者至少有办法让我不用每次到达Z都写一种情况?编辑:它应该是const char,不知道为什么VS决定不复制一些会很有趣。
您需要分离外部(对用户)表示和内部表示。
内部表示
在计算机内部,您应该使用最有效的表示。可以是十六进制,二进制或十进制;或者不用担心。
当呈现给用户时,你应该使用外部表示。
外部表示
字符数组表示数字系统的位。(也应该是const
。)你需要把数字从你的内部表示中分离出来。例如,在以16为基数的情况下,我们将数除以16,将数向右移动,并使用模除法得到余数。余数是数字值。使用余数从数组中查找数字表示。
在较小的基数上尝试算法,例如17或18。扩展到62应该是改变#define
或const integer
的问题。
编辑1:困难的方法
一个更困难的方法是用一个字节表示你的数字系统的每一个数字。字节、八位字节或无符号字符的范围为0到255,因此应该容纳以62为基数的数字。
用std::vector<unsigned char>
表示您的号码。你必须决定最高有效数字是在向量的前面还是最后。
增加一个数字:
add 1 to digit.
if digit value > 62
{
set digit to zero.
Load digit with next greater column value (i.e. vector[position + 1];
Repeat at top of algorithm
}
无论基数(10,8,16等)如何,这都是标准算法。
十进制加法、减法、乘法和除法的基本规则仍然适用。(提示)。
这是Big Number库中使用的一种技术。
以下内容可能有所帮助:(http://ideone.com/y1gZDF)(您可以根据需要更改内部表示,例如 bignnumber )。
class N62
{
public:
explicit N62(const std::string& digits) : N62(digits.c_str(), digits.size()) {}
N62(const char* digits, std::size_t len) : value(0u)
{
for (std::size_t i = 0; i != len; ++i) {
auto pos = std::find(std::begin(base), std::end(base), digits[i]);
if (pos == std::end(base)) {
throw std::runtime_error("incorrect digit");
}
value *= 62;
value += pos - std::begin(base);
}
}
N62(std::size_t value) : value(value) {}
operator std::size_t () const { return value; }
std::string str() const
{
if (value == 0u) {
return "0";
}
std::string res;
for (std::size_t n = value; n != 0; n /= 62) {
res.push_back(base[n % 62]);
}
std::reverse(res.begin(), res.end());
return res;
}
private:
std::size_t value;
private:
static constexpr char base[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
};
另外,您可以像下面这样添加一个用户字符串字面值:
N62 operator "" _n62 (const char *t, std::size_t len)
{
return N62(t, len);
}
可以这样使用:"1Z"_n62
(在123
中解析为十进制)
数字系统只是数字的表示。数字不介意我们怎么写。所以,我们的问题是:
如何使用base62在程序文本中声明数字?
你应该声明如何标记base62数字。"0x"answers"$"前缀保留为base16,"0"前缀保留为八进制,"%"前缀保留为二进制,"*"用于几种原因,也许波浪是您的前缀,例如:~Uu3n
然后,您应该编写一个预处理器,它将base62数字转换为十进制(或十六进制,根据您的需要)格式。
如何在base62中输出数字?
它是更加困难。您应该将所有数字输出转换为base62。所以
printf("%d in base62 is %D n",value,value);
应转换为
printf("%d in base62 is %s n",value,tob64(value));
不太优雅。
也许包装类应该更好(像Java中的Integer)
- 我需要帮助创建一个评分系统,但它一直给我一个错误,注释掉的整数是给我带来麻烦的部分
- 编译了一个recent-C++.因此,如果没有暴露std符号,请在旧系统上运行
- 如何制作一个根据拉取请求关闭和打开功能的构建系统?
- 在C++中,系统如何将这些对象中的每一个与执行程序的窗口相关联?
- 访问另一个类(系统)的非静态字段,就好像它是我自己的字段一样 - 优雅地
- boost::文件系统::create_directory抛出了一个提升::文件系统::filesystem_error
- 我有一个关于我的战斗系统HP代码的问题
- 如何将向量添加到结构中以创建一个库存系统,在该系统中,我可以仅使用一个结构向系统添加多种不同的葡萄酒
- 如何在另一个系统上启用文件路径
- 我正在写一个非常简单的字母评分系统,if语句是最有效的吗?
- HRESULT:将自定义代码与系统一个区分开
- 如何使用 c++ 文件系统库将文件复制到另一个目录
- 为什么更改链接顺序可以修复一个系统上的一些链接错误?
- 我的坐标系统中有一个小小的误判
- 如何使用C/C 系统调用来获取Linux过程中一个过程的当前大小
- 在64位系统上创建一个非常大的数组的缺点是什么
- 如何设置一个系统范围的挂钩以收听WM_DeviceChange
- C++:如何运行一个系统命令N次(异步)并返回N次执行时间
- Qt串行端口程序在另一个系统上运行时崩溃
- 在另一个系统上构建时禁用特定的C++行和 #includes