2012-03-28 14 views
0

こんにちは私は、整数nをとり、 '、'で区切られた1からnまでの数字を含む文字列を返します。今ではこの整数nは10億という大きな数字になります。このための最良の解決策は何か。そして、もしRAMがちょうど2Gbのようなメモリ関連の問題をどうやって管理すれば、C#でこの大きな文字列を返せばどうなりますか?関数シグネチャは、は10億の文字を含む文字列を返します

string convtostr (int n) 
{} 

です。 n = 5の場合、出力は次のような文字列になります "1,2,3,4,5"

答えて

0

メソッドフットプリントが、表示するフットプリントと正確に一致しなければならない場合は、実行できません。 Stringを継承することはできませんし、2GBを超える新しいタイプを作り直すことができません。

入力値の最大値がであると仮定すると、フットプリントと一致する解決策を提供できます。例えば、nの最大値が10000かそれとも非常に小さいものであるかのように。

しかし、私は@MikeSamuelによって提案されているように、IEnumerable<char>アプローチが、指定された要件に近づくように働く唯一の解決策であると考えています。

あなたは彼らのようなyield構文を使用した溶液を探していました。このc# 4.0ほとんどのタグを付けてきたように:あなたは、あなたが以下の

int input = 1000000000; // 1 billion. 

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

ようにそれを使用することを説明することができ

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

をそして、それはあなたが答えたいと思っていたものでしょう。これは、最終的な文字列全体を実際にはメモリに格納しないことで、非常に少ないアクティブ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構文を使用するのとほぼ同じ動作をします。

のn = 10億:

2

.NETでこのような大きな文字列を作成することはできません。 2GBは、メモリの量に関係なく、オブジェクトの最大サイズです。

文字列を返す代わりに、結果内の文字を反復処理することができますが、必要に応じて計算するオブジェクトを提供することができます。

+1

'IEnumerable '? –

+0

返事をありがとうが、これはインタビューの質問で私に尋ねられました。とにかく、オブジェクトを返す場合でも、反復される結果は依然として非常に大きくなります。だから、周りを回ることはありませんか、それは可能ではありません。 – Naphstor

+0

@Naphstor:何かを取得しますか?あなたがそれを反復したいのであれば、あなたはそれを行うには長い時間がかかるでしょう。それを繰り返す必要がない場合は、実際には何もしないため、怠惰なアプローチは非常に速くなることは明らかです。 –

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"); 
    } 
} 

それはまさにあなたの場合のように動作しますあなたがしない限り、常に文字列を含んでいました。

+0

はい、私はそれを印刷しない文字列を返す必要があります。 – Naphstor

+0

Hmmmm。私は、その文字列が何らかのオブジェクトを表現しているだけなので、このような文字列を返す**目的がないことを意味しています。非常に基本的なアプリケーションでは、このオブジェクトは単なるintです。このオブジェクトのいくつかの操作を実行する必要がある場合は、その実装を拡張できます。たとえば、オブジェクトのプリントなどの下限jは、j、...、iなどのようになります。 – iehrlich

+0

ところで、インタビューについてのあなたのコメントが表示されますので、私の答えは '正しい' (うーん...)1つ。 – iehrlich

0

のは、設計限界を見てみましょう

nは10億、あるときにカンマが「」は、単独のchar === 2つのバイトので、ご利用可能なスペースを食べます。 2バイト* 10億= 2 GB - 2バイト(実際には20億〜1カンマ)です。したがって、この基本的な見解から、2GBに収まるように結果を圧縮するというアイディアが必要です。文字列はオブジェクトであり、サイズは2GBに制限されています。

したがって、オブジェクト間でメッセージをどのようにエンコードするのですか?つまり、あるオブジェクトはnで関数を呼び出し、呼び出されたオブジェクトからのメッセージを期待します。結果を表示するのではなく、文字列を返すように求められたことに注目してください。あなたが提示した関数の署名が実際にインタビュアーがボードに書いたものであれば(それはあなたの質問の解釈ではなく)、suddnly_meからの答えはしません。そうでなければあなたの答えです。

インタビュアーが書いたものがシグネチャであると仮定すると、2つのオブジェクト間で圧縮されたメッセージをどのように送信しますか?それが響くかもしれないように、私は文字列としてnを返すだろう。

返される値がどのように使用されるかによって、メッセージをデコードするデコーダ/パーサーを記述します。たとえば、文字列をファイルに書き込む必要がある場合、ライターメソッド/関数は文字列をintに変換し、ファイルに書き込む間に1からnまで繰り返します。

私は十分な時間がかかりました。あなたはその考えを得る。

+0

はい、私は実際に同じことをやっていると感謝しています。しかし、彼は何か他のものを聞きたかったと思う。彼はあなたの入力がn = 10億であると言って続けたので、あなたが返す出力は "1,2,3,4、...、1Gb"を返すでしょう。だから私は混乱した。 – Naphstor

関連する問題