返回一个包含十亿个字符的字符串
嗨,我有一个函数,它接受一个整数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是对象的最大大小。
您可以提供一个对象,它允许您遍历结果中的字符,但仅根据需要计算它们,而不是返回字符串。
我想你最好的解决方案是不是在所有使用此字符串:)你可以在类包装这个字符串,只包含数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");
}
}
它的行为完全一样,如果你一直包含着字符串,除非你没有。
让我们来看看在设计极限:
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。
我已经走了很久。你明白了。
是的,谢谢我其实也是这么想的。但我想他想听听别的。因为他一直说你的输入是n = 10亿,所以你返回的输出将返回“1,2,3,4,...,1Gb”。所以我感到困惑。 – Naphstor 2012-04-09 15:09:12
'IEnumerable'? –
2012-03-28 23:59:37
感谢您的回复,但这是在面试问题中问我的。无论如何,即使我返回一个对象,迭代的结果仍然是非常大的。那么有没有什么可以解决的,或者是不可能的。 – Naphstor 2012-03-28 23:59:52
@Naphstor:绕过什么?如果你想迭代它,那么无论你做什么,它都需要很长时间。如果你不需要迭代它,那么显然懒惰的方法会非常快,因为它实际上不会做任何事情。 – 2012-03-29 00:07:15