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

问题描述:

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

string convtostr (int n) 
{} 

因此输入例如可能是n = 5,那么输出将是这样一个字符串 “1,2,3,4,5”

如果您的方法足迹必须与您显示的方法足迹完全匹配,则无法完成。因为您不能继承String并创建一个适用于> 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语法几乎相同。

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

您可以提供一个对象,它允许您遍历结果中的字符,但仅根据需要计算它们,而不是返回字符串。

+1

'IEnumerable '? – 2012-03-28 23:59:37

+0

感谢您的回复,但这是在面试问题中问我的。无论如何,即使我返回一个对象,迭代的结果仍然是非常大的。那么有没有什么可以解决的,或者是不可能的。 – Naphstor 2012-03-28 23:59:52

+0

@Naphstor:绕过什么?如果你想迭代它,那么无论你做什么,它都需要很长时间。如果你不需要迭代它,那么显然懒惰的方法会非常快,因为它实际上不会做任何事情。 – 2012-03-29 00:07:15

我想你最好的解决方案是不是在所有使用此字符串:)你可以在类包装这个字符串,只包含数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"); 
    } 
} 

它的行为完全一样,如果你一直包含着字符串,除非你没有。

+0

是的,但我必须返回一个字符串不打印它。 – Naphstor 2012-03-29 00:01:06

+0

嗯。我的意思是,我没有看到**返回这样一个字符串的目的,因为字符串只是某个对象的表示。在非常基本的应用程序中 - 这个对象只是一个int。如果您需要执行此对象的某些操作,则可以增强其实现。例如,对于下界j,例如对象的打印将看起来像j,...,i等。 – iehrlich 2012-03-29 00:04:51

+0

顺便说一句,我看到您对采访的评论,所以我想我的答案会是“正确的” (嗯...)一个。 – iehrlich 2012-03-29 00:05:52

让我们来看看在设计极限:

N = 1十亿:

n为1时十亿,那么逗号“”独吃你的可用空间,因为焦炭=== 2个字节;所以2个字节* 10亿= 2 GB - 2个字节(你实际上有20亿 - 1个逗号)。因此,从这个基本观察来看,这个想法必须是压缩结果以适应2GB。字符串是一个对象,大小限制为2GB。

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

假设签名是面试官写的,那么如何在两个对象之间发送压缩的消息?尽可能听起来很滑稽,我会以字符串的形式返回n。

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

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

我已经走了很久。你明白了。

+0

是的,谢谢我其实也是这么想的。但我想他想听听别的。因为他一直说你的输入是n = 10亿,所以你返回的输出将返回“1,2,3,4,...,1Gb”。所以我感到困惑。 – Naphstor 2012-04-09 15:09:12