【问题标题】:Convert an int [] to string without an explicit for loop in C++将 int [] 转换为字符串,而无需在 C++ 中使用显式 for 循环
【发布时间】:2018-06-09 15:12:42
【问题描述】:

我需要将int[] 转换为字符串。有std::to_string 方法,但它不接受数组作为输入。因此,需要一个 for 循环 like here。有没有一种方法可以在没有显式 for 循环的情况下实现这一目标?就像在 Java 中一样,我们可以为此使用 java.util.Arrays.toString()

编辑:任何可能的解决方法都会有所帮助,以优化的方式解决问题。

【问题讨论】:

  • 没有标准的join 函数,这是您通常将集合转换为字符串的方式。当然,它仍然存在于其他库中。
  • 最终会出现一个循环,无论是您自己编写还是被语言结构隐藏。编写一个函数,调用它,然后继续。
  • 不要将short 与optimized 混淆,尤其是当您不确切知道隐藏在漂亮包装器后面的代码中发生了什么时。测量,然后优化。如果不进行测量,您无法判断一件事比另一件事快,您也无法判断您是否专注于错误的事情。
  • std::for_each如果你想要一个函数看看for

标签: c++ arrays string


【解决方案1】:

您可以通过使用一些元编程来避免循环。这个想法是在编译时展开循环:

首先,使用引用来避免数组到指针的衰减。这样,您可以推断出数组的大小。您使用该大小生成从 0 到 size-1 的编译时 std::size_t 序列,并将数组和序列提供给实现函数:

template <std::size_t N>
std::string to_string(int (&array)[N]) {
    return to_string_impl(array, std::make_index_sequence<N>());
}

在第二个函数中,您使用参数包扩展来生成展开循环:

template <std::size_t N, std::size_t... Ns>
std::string to_string_impl(int (&array)[N], std::index_sequence<Ns...>) {
    std::ostringstream os;
    std::ostream_iterator<int> out(os, " ");
    int dummy[sizeof...(Ns)] = { (os << array[Ns], 0)... };
    /* generates:
       os << array[0]
       ...
       os << array[N-1]
    */
    return os.str();
}

注意:不要忘记包括:

#include <iostream>
#include <utility>
#include <sstream>
#include <iterator>

那么你就有了:

int main() {
    int arr[] = {1,2,3,4,5};
    std::cout << to_string(arr); // prints "12345"
}

【讨论】:

  • 一个有趣的解决方案。但是,应该提到它只适用于在编译期间已知大小的数组。
  • @InnokentiyAlaytsev:是的,我忘记了我们也可以在 C++ 中访问运行时大小的数组......从 C++17 开始?
  • @papagaga,还没有运行时大小的数组。已经努力解决所涉及的问题,但尚未得出结论。
  • Visual Studio 在表示递归类型太复杂之前只允许数组中有 1024 个元素。我有点惊讶它涨到那么高,它过去跌倒的速度要快得多。巧妙的把戏。 :)
【解决方案2】:

这样就可以了

 #include <iostream>       
 #include <sstream>      
 #include <iterator>       
 #include <algorithm>
 #include <string>

 int main()
 {
      int x[] = {1,2,3,4,5};     // sample array

      std::ostringstream os;
      std::ostream_iterator<int> out(os, " ");
      std::copy(std::begin(x), std::end(x), out);
      std::string result = os.str();
 }

请记住,result 在最后一个 int 值之后会有一个尾随空格。我会把删除它作为练习。

有点神秘。

      std::ostringstream os;
      std::copy(std::begin(x), std::end(x), std::ostream_iterator<int>(os, " "));
      std::string result = os.str();

在 C++ 中,您不会得到与 Java 完全相同的东西,因为 int [] 在 C++ 中比在 Java 中更原始。例如,当作为参数传递给函数时,数组将转换为指向其第一个元素的指针,因此被调用的函数不会接收有关元素数量的信息。

【讨论】:

  • 也许,也许不是。 std::copy 只是一个循环的包装器。代码的大小很少表明它的效率。与 30 行展开循环相比,我可以向您展示一个可怕的单行。但是,如果两者都不是真正成为代码瓶颈的地方,那又有什么关系呢?
  • @IbrahimYousaf - 也许吧。这是实施质量问题。没有什么可以阻止std::copy() 使用一些编译器或特定于机器的魔法来击败循环,但同样没有什么可以阻止它。如果您想确定,请在有代表性的目标系统上进行基准测试。
  • FWIW,有一个 ostream_joiner 用于额外的空间,但它在 TS 中。无论如何,给定数组时,函数也可以获取大小信息。它只需要通过引用获取数组,而不是接受指向第一个元素的指针。
【解决方案3】:

试试这个

#include <sstream>
#include <string>
#include <iostream>

std::string ToString(int number)
{
    std::string str;
    std::stringstream ssout;
    ssout << number;
    str = ssout.str(); 
    return str;
}
int main()
{
    std::string mystr;
    mystr = ToString(1234);
    std::cout<<mystr<<std::endl;
    getchar();
    return 0;
}

【讨论】:

  • 我有一个很大的 int [] 可以转换成字符串。
  • 这根本不能回答问题。问题是关于对整个数组进行字符串化,而您的答案中根本没有数组。另外,没有必要再使用ToString 来实现std::to_string 等等。
  • stringising - 超级。
猜你喜欢
  • 2020-10-31
  • 2013-09-10
  • 2021-11-13
  • 2019-09-10
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多