嗨,我有一個函數,它接受一個整數n並返回一個字符串,其中包含由','分隔的數字1到n。現在這個數字的整數n可以是任何數量大到10億的數字。這可能是最好的解決方案。我如何管理內存相關的問題,如果RAM只是2 GB,那麼如果我在C#中返回這個大字符串會發生什麼。函數簽名是:返回一個包含十億個字符的字符串
string convtostr (int n)
{}
因此輸入例如可能是n = 5,那麼輸出將是這樣一個字符串 「1,2,3,4,5」
嗨,我有一個函數,它接受一個整數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