如何将十进制字符串转换为二进制字符串
How to convert a decimal string to binary string?
我有一个像这样的十进制字符串(长度<5000):
std::string decimalString = "555";
有没有一种标准的方法可以将这个字符串转换为二进制表示?像这样:
std::string binaryString = "1000101011";
更新
这篇文章帮助了我。
由于数字非常大,您可以使用一个大的整数库(可能是boost?),或者自己编写必要的函数。
如果您决定自己实现这些函数,一种方法是在代码中实现旧的铅笔和纸的长除法,在这种方法中,您需要将十进制数反复除以2
,并将余数累积到另一个字符串中。可能有点麻烦,但除以2应该不会那么难。
由于10不是2的幂(或相反),所以你运气不好。你必须用10进制来实现算术运算。您需要以下两种操作:
- 整数除以2
- 检查除以2后的余数
两者都可以通过相同的算法进行计算。或者,您可以使用C++的各种大整数库之一,如GNU MP或Boost.Multiprecision.
我试过了。。我认为我的答案不对,但这是我试图做的事情背后的想法。。
假设我们有两个小数:
100和200.
为了连接这些,我们可以使用公式:
a * CalcPower(b) + b
,其中CalcPower定义如下。。
知道了这一点,我试着把很长的十进制字符串分成4块。我将每个字符串转换为二进制,并将它们存储在一个向量中。。
最后,我遍历每个字符串,并应用上面的公式将每个二进制字符串连接成一个大字符串。。
我没有让它工作,但这是代码。。也许其他人看到了我的错误。。BinaryAdd
、BinaryMulDec
、CalcPower
工作得非常好。。问题实际上在ToBinary
中
#include <iostream>
#include <bitset>
#include <limits>
#include <algorithm>
std::string BinaryAdd(std::string First, std::string Second)
{
int Carry = 0;
std::string Result;
while(Second.size() > First.size())
First.insert(0, "0");
while(First.size() > Second.size())
Second.insert(0, "0");
for (int I = First.size() - 1; I >= 0; --I)
{
int FirstBit = First[I] - 0x30;
int SecondBit = Second[I] - 0x30;
Result += static_cast<char>((FirstBit ^ SecondBit ^ Carry) + 0x30);
Carry = (FirstBit & SecondBit) | (SecondBit & Carry) | (FirstBit & Carry);
}
if (Carry)
Result += 0x31;
std::reverse(Result.begin(), Result.end());
return Result;
}
std::string BinaryMulDec(std::string value, int amount)
{
if (amount == 0)
{
for (auto &s : value)
{
s = 0x30;
}
return value;
}
std::string result = value;
for (int I = 0; I < amount - 1; ++I)
result = BinaryAdd(result, value);
return result;
}
std::int64_t CalcPowers(std::int64_t value)
{
std::int64_t t = 1;
while(t < value)
t *= 10;
return t;
}
std::string ToBinary(const std::string &value)
{
std::vector<std::string> sets;
std::vector<int> multipliers;
int Len = 0;
int Rem = value.size() % 4;
for (auto it = value.end(), jt = value.end(); it != value.begin() - 1; --it)
{
if (Len++ == 4)
{
std::string t = std::string(it, jt);
sets.push_back(std::bitset<16>(std::stoull(t)).to_string());
multipliers.push_back(CalcPowers(std::stoull(t)));
jt = it;
Len = 1;
}
}
if (Rem != 0 && Rem != value.size())
{
sets.push_back(std::bitset<16>(std::stoull(std::string(value.begin(), value.begin() + Rem))).to_string());
}
auto formula = [](std::string a, std::string b, int mul) -> std::string
{
return BinaryAdd(BinaryMulDec(a, mul), b);
};
std::reverse(sets.begin(), sets.end());
std::reverse(multipliers.begin(), multipliers.end());
std::string result = sets[0];
for (std::size_t i = 1; i < sets.size(); ++i)
{
result = formula(result, sets[i], multipliers[i]);
}
return result;
}
void ConcatenateDecimals(std::int64_t* arr, int size)
{
auto formula = [](std::int64_t a, std::int64_t b) -> std::int64_t
{
return (a * CalcPowers(b)) + b;
};
std::int64_t val = arr[0];
for (int i = 1; i < size; ++i)
{
val = formula(val, arr[i]);
}
std::cout<<val;
}
int main()
{
std::string decimal = "64497387062899840145";
//6449738706289984014 = 0101100110000010000100110010111001100010100000001000001000001110
/*
std::int64_t arr[] = {644, 9738, 7062, 8998, 4014};
ConcatenateDecimals(arr, 5);*/
std::cout<<ToBinary(decimal);
return 0;
}
我找到了解决体育编程任务的旧代码:
ai->aj
2<=i、 j<=36;0<=a<=10^1000
时限:1秒
在最坏的情况下,执行时间约为0039。由于使用10^9作为计数系统,乘法、加法和除法算法非常快,但我认为可以很好地优化实现。
源链路
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define sz(x) (int((x).size()))
typedef vector<int> vi;
typedef long long llong;
int DigToNumber(char c) {
if( c <= '9' && c >= '0' )
return c-'0';
return c-'A'+10;
}
char NumberToDig(int n) {
if( n < 10 )
return '0'+n;
return n-10+'A';
}
const int base = 1000*1000*1000;
void mulint(vi& a, int b) { //a*= b
for(int i = 0, carry = 0; i < sz(a) || carry; i++) {
if( i == sz(a) )
a.push_back(0);
llong cur = carry + a[i] * 1LL * b;
a[i] = int(cur%base);
carry = int(cur/base);
}
while( sz(a) > 1 && a.back() == 0 )
a.pop_back();
}
int divint(vi& a, int d) { // carry = a%d; a /= d; return carry;
int carry = 0;
for(int i = sz(a)-1; i >= 0; i--) {
llong cur = a[i] + carry * 1LL * base;
a[i] = int(cur/d);
carry = int(cur%d);
}
while( sz(a) > 1 && a.back() == 0 )
a.pop_back();
return carry;
}
void add(vi& a, vi& b) { // a += b
for(int i = 0, c = 0, l = max(sz(a),sz(b)); i < l || c; i++) {
if( i == sz(a) )
a.push_back(0);
a[i] += ((i<sz(b))?b[i]:0) + c;
c = a[i] >= base;
if( c ) a[i] -= base;
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int from, to; cin >> from >> to;
string s; cin >> s;
vi res(1,0); vi m(1,1); vi tmp;
for(int i = sz(s)-1; i >= 0; i--) {
tmp.assign(m.begin(), m.end());
mulint(tmp,DigToNumber(s[i]));
add(res,tmp); mulint(m,from);
}
vi ans;
while( sz(res) > 1 || res.back() != 0 )
ans.push_back(divint(res,to));
if( sz(ans) == 0 )
ans.push_back(0);
for(int i = sz(ans)-1; i >= 0; i--)
cout << NumberToDig(ans[i]);
cout << "n";
return 0;
}
如何"从->至";为字符串"工作";s":
- 累加大数(vector<int>)"res";其中s[i]*来自^(|s|-i-1),i=|s|-1..0
- 通过除以"0"来计算数字;res";通过";至";直到res>0并将其保存到另一个矢量
- 将其逐位发送到输出(您可以使用ostringstream)
PS我注意到线程启动器的昵称是Denis。我认为这个链接可能也很有用。
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 如何将这个std::字符串转换为std::基本字符串
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 如何在C++中将十六进制字符串转换为文本数据
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 如何从字符串转换为双精度*
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- 如何在C++中将 Python 字符串转换为其转义版本?
- 如何在 C++11 中将标准::字符串转换为标准::u32字符串?
- 如何将整数字符串转换为整数的二维向量?
- 使用 "stringstream " 将字符串转换为整数
- 将字符串转换为浮点数或整数,而无需使用内置函数(如 atoi 或 atof)
- 将文件复制到自定义位置,存在字符串转换问题
- 将ANSI C字符串转换为UNICODE
- 如何将节点 V8 字符串转换为 C++ 字符串
- 在C++中将字符串转换为双精度,而无需科学记数法
- 使用从文件(stod、strtod、atof)中提取的数据C++从字符串转换为双精度.csv
- 如何在C++中将字符串转换为双精度?
- 将字符串转换为无符号字符数组/字节数组