有没有一种方法可以将以字符串表示的数字转换为二进制数?

4

所需代码的外壳:

#include <iostream>
#include <string>

std::string str_to_bin(const std::string& str)
{
    //...
}

int main()
{
    std::string str = "123";

    std::cout << str_to_bin(str); //would print 1111011
}

问题标题已经说明了一切。我已经被困在这个问题上一段时间了,STL中是否有解决方案?或者是我忽略了一些简单的东西吗?如果没有,我该如何处理呢?也许你可以指点我一个方向?同时,速度非常重要。
编辑:数字可以是任意大小(大于long long),因此std::stoi和std::bitset<>都无法使用。

尝试过这个:https://dev59.com/3Wkw5IYBdhLWcg3wBmCA? - loxxy
你需要多精度算术来完成这个任务:https://en.wikipedia.org/wiki/List_of_C%2B%2B_multiple_precision_arithmetic_libraries - user2249683
如果大小是一个问题,可以使用boost::dynamic_bitset - edmz
2个回答

3
你可以使用GMP(GNU多精度)来完成。类似这样:

GMP (GNU Multi-Precision)

#include <gmpxx.h>

std::string str_to_bin(const std::string& str)
{
    mpz_class bignum;
    int rc = bignum.set_str(str, 10);
    if (rc != 0)
        throw std::invalid_argument("bad number: " + str);

    return bignum.get_str(2);
}

或者使用传统的C API:

#include <gmp.h>

std::string str_to_bin(const std::string& str)
{
  mpz_t bignum;
  int rc = mpz_set_str(bignum, str.c_str(), 10);
  if (rc != 0)
    throw std::invalid_argument("bad number: " + str);

  char* rawstr = mpz_get_str(nullptr, 2, bignum);
  std::string result(rawstr);
  free(rawstr);
  return result;
}

0

好的,让我们来分解一下你需要的过程。(这只是其中一种无数种方法之一)

  1. 将以字符串类型表示的数字转换为整数类型。
  2. 将中间整数类型转换为二进制数,该二进制数保存在另一个字符串类型中。(根据您函数的返回类型,它也可以轻松地返回一个整数,并避免将二进制等效项表示为字符串的麻烦)

对于步骤1:

使用标准库函数 stoi()。它会提取字符串中的数字数据并将其存储在整数中。

std::string numberstr = "123";
int numberint = std::stoi(numberstr);
std::cout << numberint << "\n";

现在你已经有了一个整数。

第二步:

  1. 这个过程涉及将一个数字从十进制转换为二进制。
  2. 将数字除以2。
  3. 存储此除法操作的余数和商以供进一步使用。
  4. 余数成为二进制表示的一部分,而商则用作下一个被除数。
  5. 此过程重复,直到被除数变为1,此时它也包含在二进制表示中。
  6. 反转字符串,完成!您现在拥有一个数字的二进制表示。

  7. 如果您想处理负数(我想您可能会),只需在转换之前执行检查,以查看转换后的整数是否为负数,并在其为真时设置标志。

  8. 在反转之前检查此标志,并在反转之前在字符串末尾添加负号。

最终函数如下:

std::string str_to_bin(const std::string& str)
{
    std::string binarystr = ""; // Output string

    int remainder;
    int numberint = std::stoi(str);
    bool flagnegative = false;
    // If negative number, beginning of binary equivalent is 1
    if (numberint < 0)
    {
        numberint = abs(numberint);
        flagnegative = true;
    }
    // If number is 0, don't perform conversion simply return 0
    if (numberint == 0)
    {
        binarystr = "0";
        return binarystr;
    }
    std::cout << numberint << "\n";

    while (numberint != 1)
    {
        remainder = numberint % 2;
        numberint /= 2;
        std::ostringstream convert; // stream used for the conversion
        convert << remainder;      // insert the textual representation of 'remainder' in the characters in the stream
        binarystr += convert.str();
    }
    std::ostringstream final;
    final << numberint;         // To insert the last (or rather first once reversed) binary number
    binarystr += final.str();
    if (flagnegative == true)
        binarystr += "-";
    std::reverse(binarystr.begin(), binarystr.end());
    return binarystr;
}

其他人已经发布了使用bitset的STL方法,这可能对您有价值,但我认为简单地复制粘贴在线找到的函数没有乐趣。

通过这种方式,您可以完全理解发生了什么!但是我无法保证速度,特别是因为这使用流。位操作肯定更有效率。

总之,希望这有所帮助!我写这个非常开心。


好的,这是在编辑之前发布的。我相信这个解决方案确实无法处理超过一定大小的变量。 - Sai Narayan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接