返回包含十亿个字符的字符串

时间:2012-03-28 23:46:08

标签: string c#-4.0

我有一个带整数n的函数并返回一个字符串,其中包含从1到n的数字,用','分隔。现在这个数字整数n可以是任何数字,大到10亿。什么是最好的解决方案。我如何管理内存相关的问题,如果RAM只有2 Gb,那么如果我在C#中返回这个大字符串会发生什么。功能签名是:

string convtostr (int n)
{}

所以输入例如可能是n = 5,然后输出将是这样的字符串     “1,2,3,4,5”

4 个答案:

答案 0 :(得分:2)

您无法在.NET中创建如此大的字符串。无论你有多少内存,2GB都是对象的最大大小。

您可以提供一个对象,它允许您迭代结果中的字符,但只能按需计算它们,而不是返回字符串。

答案 1 :(得分:2)

我想最好的解决方案就是不要使用这个字符串:)你可以将这个字符串包装在一个只包含数字n的类中:

class LargeStringWithNumbers
{
  int upper_bound;
  public void Print()
  {
    for (int j = 0; j < upper_bound; j++ )
    {
      System.Console.Write("{0};", j);
    }
    System.Console.Write("\n");
  }
}

它的行为与您始终包含字符串的行为完全相同,除非您不这样做。

答案 2 :(得分:0)

如果您的方法足迹必须与您显示的足迹完全匹配,则无法完成。因为您无法继承String并创建一个适用于&gt; 2GB的新更好的类型

如果您对n的最大输入值的假设不正确,那么您可以提供匹配足迹的工作解决方案。例如n的最大值是10000还是非常小。

但是我认为@MikeSamuel建议的IEnumerable<char>方法是唯一能够提供接近所述要求的工作解决方案的答案。

正如您标记了此c# 4.0他们很可能正在寻找使用yield语法的解决方案,例如:

static IEnumerable convtostr(int n)
{
    for (int i = 1; i < n; i++)
        yield return string.Format("{0}, ", i.ToString());
    yield return n.ToString();
}

然后您可以解释您使用它,如下所示

int input = 1000000000; // 1 billion.

foreach (var value in convtostr(input))
{
    Console.Write(value );
}

这很可能是他们想要你回答的。由于实际上不会将整个最终字符串存储在内存中,因此这将适用于非常少的活动RAM。

编辑:与@suddnely_me建议类似的另一个答案是为每个号码传递一个操作,例如:

static void convtostr(int n, Action<int> action)
{
    for (int i = 1; i <= n; i++)
        action(i);
}

然后使用:

调用它
int input = 1000000000; // 1 billion.
convtostr(input, n =>
    {
        if (n < input) { Console.Write("{0}, ", n); }
        else { Console.Write(n); }
    });

实际上与使用yield语法几乎相同。

答案 3 :(得分:0)

让我们看看设计限制:

n = 10亿:

当n为10亿时,则逗号“,”单独占用您的可用空间,因为char === 2个字节;这样2个字节* 10亿= 2 GB - 2个字节(实际上你有20亿个 - 1个逗号)。因此,从这个基本观察来看,想法必须是将结果压缩到2GB。 String是一个对象,大小限制为2GB。

因此,问题是如何在对象之间编码消息?即,一个对象将使用n调用该函数,并期望来自被调用对象的消息。请注意,您没有被要求打印结果,而是返回一个字符串。如果你提出的功能签名实际上是面试官在董事会上所写的内容(而不是你对问题的解释),那么来自suddnly_me的答案就不行了,否则就是你的答案。

假设签名是面试官写的,那么如何在两个对象之间发送压缩消息呢?虽然听起来很滑稽,但我会把n作为字符串返回。

 string convtostr (int n)
 {
  return n+"";
 }

然后根据返回值的用途,我会编写解码器/解析器来解码消息。例如,如果调用需要将字符串写入文件,则编写器方法/函数会将字符串转换回int,并在写入文件时从1到n进行迭代。

我已经走了很长时间。你明白了。