35

projecteuler.netの問題を解決しようとしていますが、いくつかの問題に直面し続けています。

1 つ目は、大量の要素を に格納するという問題ですList<t>。リストに大量に保存すると、OutOfMemoryException が発生し続けます。

これらのことを最善の方法で行っていない可能性があることは認めますが、アプリが消費できるメモリ量を定義する方法はありますか?

通常、100,000,000 個の要素を取得するとクラッシュします:S

第二に、いくつかの質問では膨大な数を追加する必要があります。数値が非常に大きくなると思われる ulong データ型を使用しますが、サポートされている最大の int を超えてラップし、負の数値に入ることができます。

信じられないほど大きな数を扱うためのヒントはありますか?

4

11 に答える 11

33

System.Numerics.BigIntegerを検討してください。

于 2008-11-10T20:28:41.070 に答える
28

これらの操作を分割するには、いくつかの基本的な数学プリンシパルを使用する多数のクラスを使用する必要があります。このCodePojectでの C# BigInteger ライブラリの実装は、最も有望なようです。この記事には、膨大な数の操作がどのように機能するかについての良い説明もあります。

参照: C# の大きな整数

于 2008-11-10T20:26:16.080 に答える
11

Project Euler に関する限り、OutOfMemory 例外が発生している場合、間違ったツリーを表示している可能性があります。彼らのウェブサイトから:

各問題は「1 分ルール」に従って設計されています。つまり、より困難な問題で成功するアルゴリズムを設計するには数時間かかる場合がありますが、効率的な実装により、適度なパワーのコンピューターで 1000 分の 1 のソリューションを得ることができます。 1分未満。

于 2008-11-10T20:39:25.383 に答える
4

ユーザーJakersが言ったように、Big Numbersを使用している場合は、おそらく間違っています。

私が行ったProjectEulerの問題のうち、これまでに大量の計算を必要としたものはありません。大きな数字を避けるための適切なアルゴリズムを見つけることについての詳細です。

ヒントが欲しいですか?ここに投稿すると、興味深いオイラースレッドが開始される可能性があります。

于 2009-01-16T17:25:27.317 に答える
3

これはC#だと思いますか?F# には、これらの問題 (BigInt 型と遅延シーケンス) の両方を処理する方法が組み込まれています。

必要に応じて、C# の両方の F# 手法を使用できます。コア F# アセンブリへの参照を追加すると、BigInt 型は他の言語から合理的に使用できます。

遅延シーケンスは、基本的に構文に適した列挙子です。1 億個の要素をリストに入れるのは良い計画ではないので、それを回避するためにソリューションを再考する必要があります。情報を保持する必要がない場合は、破棄してください。保存するよりも再計算する方が安い場合は、破棄してください。

于 2008-11-10T20:28:44.813 に答える
1

アプリが使用するメモリの量を定義する限り、 MemoryFailPointクラスを使用して、操作を実行する前に使用可能なメモリを確認できます。

これにより、操作を実行する前にメモリを事前に割り当てることができるため、操作を実行する前に操作が失敗するかどうかを確認できます。

于 2008-11-11T08:55:33.243 に答える
1

このスレッドの回答を参照してください。おそらく、利用可能なサードパーティ製の大きな整数ライブラリ/クラスのいずれかを使用するか、ネイティブの BigInteger データ型を含む C# 4.0 を待つ必要があります。

于 2008-11-10T20:26:54.833 に答える
0

それがそれを処理する良い方法であるかどうかはわかりませんが、私のプロジェクトでは以下を使用しています。

各項目に「double theRelevantNumber」変数と「int PowerOfTen」があり、関連するクラスには「int relatedDecimals」変数があります。

そのため...大きな数が発生した場合、次のように処理されます。

まず、x,yyy 形式に変更されます。したがって、数値 123456,789 が入力され、「powerOfTen」が 10 の場合、次のように開始されます。

theRelevantNumber = 123456,789 PowerOfTen = 10 その時の数値: 123456,789*10^10

その後、次のように変更されます: 1,23456789*10^15

次に、関連する小数点以下の桁数 (たとえば 5) で 1,23456 に丸められ、「PowerOfTen = 15」と共に保存されます。

数値を加算または減算する場合、関連する小数以外の数値は無視されます。あなたが取る場合の意味:

1*10^15 + 1*10^10 "relevantDecimals" が 5 の場合は 1,00001 に変更されますが、"relevantDecimals" が 4 の場合はまったく変更されません。

このメソッドを使用すると、doubleLimit*10^intLimit までの数値を問題なく処理できます。少なくとも OOP の場合、追跡するのはそれほど難しくありません。

于 2018-12-14T13:38:16.783 に答える
0
string Add(string s1, string s2)
{
        bool carry = false;
        string result = string.Empty;

        if (s1.Length < s2.Length)
            s1 = s1.PadLeft(s2.Length, '0');
        if(s2.Length < s1.Length)
            s2 = s2.PadLeft(s1.Length, '0');

        for(int i = s1.Length-1; i >= 0; i--)
        {
            var augend = Convert.ToInt64(s1.Substring(i,1));
            var addend = Convert.ToInt64(s2.Substring(i,1));
            var sum = augend + addend;
            sum += (carry ? 1 : 0);
            carry = false;
            if(sum > 9)
            {
                carry = true;
                sum -= 10;
            }
            result = sum.ToString() + result;
        }
        if(carry)
        {
            result = "1" + result;
        }

    return result;
}
于 2018-05-20T16:15:51.423 に答える