0

そのため、Objective-C で Project Euler problem 25 に取り組んでおり、NSDecimalNumberのサイズ制限に遭遇しました。intそこで、他のコード ライブラリの使用を試みた後、フィボナッチ数を最初は s の配列として、次にNSArrays のsとして再表現することにしましたNSNumber。配列内の各セルは 1 桁になります。次に、1000 桁目まで桁ごとに大きな数を加算できます。残念ながら、何かがうまくいかず、キャリーは正しいのですが、最後のキャリーの前の桁が常にゼロのようです。

8 番目のフィボナッチ数と 12 番目のフィボナッチ数を計算してみましたが、同じ動作が得られました。13 と 144 を取得する代わりに、10 と 104 を取得します。数字を正しく合計しますが、

[nextFib insertObject: [NSNumber numberWithInt:digitSum] atIndex: arrayIndex]; 

私が期待することをしていないようです。digitSum は両方のインスタンスで 3 と 4 ですが、メソッドが次のフィボナッチ数を NSArray として返すと、3 または 4 を期待していたところに 0 が返されます。時々うまくいくように見えますが、その場で作成した NSNumber が期待どおりの値を持っていないこともあります。ここに私の方法全体があります:

+ (NSArray*) nextBigFibonancci: (NSArray*) fibZero After: (NSArray*) fibOne
{
  // It's come to manually adding digits in one thousand count arrays.
  // I can't return or pass arrays... will have to use NSArrays for everything, version at least 4.0
  // Since XCode 4.5 I can use array[i] and other array literals... Lets just get it working...

  // Works for Fib 1 and Fib 2 and Fib 3, but not Fib 12...

  int fibZeroDigits = [fibZero count];
  int fibOneDigits = [fibOne count];
  NSMutableArray*  nextFib = [NSMutableArray arrayWithCapacity:1000];
  NSArray* number;
  int arrayIndex = 999;
  int cellCount = fibZeroDigits - 1;
  int digitZero, digitOne, digitSum;

  // There is an Objective-c loop structure for looping through all objects in array, but stick to this...
  for (int j = 0; j < 1000; j++)
  {
    // All the integers must be zero.
    [nextFib insertObject: [NSNumber numberWithInt:0] atIndex: j];
  }

  for (int i = fibOneDigits; i > 0; i--)
  {
    digitZero = [[fibZero objectAtIndex: cellCount] intValue];
    digitOne = [[fibOne objectAtIndex: i - 1] intValue];
    NSLog(@"arrayIndex is: %i", arrayIndex); // arrayIndex seems correct why am I getting 104?
    if (digitZero + digitOne < 10)
    {
        digitSum = digitZero + digitOne + [[nextFib objectAtIndex: arrayIndex] intValue];
        [nextFib insertObject: [NSNumber numberWithInt:digitSum] atIndex: arrayIndex];
    }
    else
    {
        digitSum = digitZero + digitOne - 10 + [[nextFib objectAtIndex:arrayIndex] intValue];
        // This isn't working the second time, though digitSum is added correctly...
        // Getting 1,0,4 for fibTwelve instead of 144
        // Doesn't work for fibEight get 1,0 instead of 13...
        [nextFib insertObject: [NSNumber numberWithInt:digitSum] atIndex: arrayIndex]; 
        [nextFib insertObject: [NSNumber numberWithInt: 1] atIndex: arrayIndex -1];
    }
    arrayIndex = arrayIndex - 1;
    cellCount = cellCount - 1;
  }
  // Must carry the last digit in fibOne if arrays are of different sizes...

  if (fibZeroDigits < fibOneDigits)
  {
    // fibOne has one extra digit
    digitSum = [[fibOne objectAtIndex:0] intValue] + [[nextFib objectAtIndex:arrayIndex - 1] intValue];
    [nextFib insertObject:[NSNumber numberWithInt:digitSum] atIndex:arrayIndex -1];
  }

  // Shouldn't return nextFib, but only the signifigant, ie non zero integers

  // Find first non zero digit and then the range from there until the end of the array nextFib
  for(int n = 0; n < 1000; n++)
  {
    if ([[nextFib objectAtIndex: n] intValue] > 0)
    {
        // First non zero digit.
        NSRange theRange;

        theRange.location = n;
        theRange.length = 1000 - n;

        number = [nextFib subarrayWithRange:theRange];
        break; // Could set n = 1000 which would also break...
     }
   }


  return number;
}

持ち運びが必要なときに、それを使って作成したものが期待どおりに保存されない理由はdigitSumありますか?NSNumber

4

2 に答える 2

1

上でほのめかしたように、私は自分のバグとさらにいくつかのバグを見つけました。insertObjectAtIndex は、まったく新しいオブジェクトを NSMutableArray に追加します。代わりに、前の数字を新しく計算された数字に置き換える ObjectAtIndexWith を置き換えたいと思いました。

XCode が更新され、デバッガーから NSArray の内部を調べる機能が追加されました。これは 2 つの 1000 桁の数字を加算する方法です。さらに大きな数字を加算するように変更できます。フィボナッチ数である必要はありません。

+ (NSArray*) nextBigFibonancci: (NSArray*) fibZero After: (NSArray*) fibOne
{    
    int fibZeroDigits = [fibZero count];
    int fibOneDigits = [fibOne count];
    int loops = fibZeroDigits - 1;
    int fibOneIndex = loops;
    NSMutableArray*  nextFib = [NSMutableArray arrayWithCapacity:1000];
    NSArray* number;
    int arrayIndex = 999;
    int digitZero, digitOne, digitSum;

    // There is an Objective-c loop structure for looping through all objects in array, but I'll just stick to this...
    for (int j = 0; j <= arrayIndex; j++) 
    {
        // All the integers start at zero.
        [nextFib insertObject: [NSNumber numberWithInt:0] atIndex: j];
    }

    if (fibOneDigits > fibZeroDigits)
    {
        fibOneIndex++;
    }

    for (int i = loops; i >= 0; i--)
    {
        digitZero = [[fibZero objectAtIndex: i ] intValue];
        digitOne = [[fibOne objectAtIndex: fibOneIndex ] intValue];
        // Have to use replaceObjectAtIndex not insertObjectAtIndex!
        digitSum = digitZero + digitOne + [[nextFib objectAtIndex: arrayIndex] intValue];
        if (digitSum < 10)
        {
            [nextFib replaceObjectAtIndex: arrayIndex withObject: [NSNumber numberWithInt:digitSum]];
        }
        else
        {
            digitSum = digitSum - 10;
            [nextFib replaceObjectAtIndex: arrayIndex withObject: [NSNumber numberWithInt:digitSum]];
            [nextFib replaceObjectAtIndex: arrayIndex -1 withObject: [NSNumber numberWithInt:1]];
        }
        arrayIndex = arrayIndex - 1;
        fibOneIndex = fibOneIndex -1;
    }
    // Must carry the last digit in fibOne if arrays are of different sizes...

    if (fibZeroDigits < fibOneDigits)
    {
        // fibOne has one extra digit
        digitSum = [[fibOne objectAtIndex:0] intValue] + [[nextFib objectAtIndex:arrayIndex] intValue];
        [nextFib replaceObjectAtIndex: arrayIndex withObject: [NSNumber numberWithInt:digitSum]];
    }

    // Shouldn't return nextFib, but only the signifigant, ie non zero integers
    // Find first non zero digit and then the range from there until the end of the array nextFib
    for(int n = 0; n < 1000; n++)
    {
        if ([[nextFib objectAtIndex: n] intValue] > 0)
        {
            // First non zero digit.
            NSRange theRange;

            theRange.location = n;
            theRange.length = 1000 - n;  

            number = [nextFib subarrayWithRange:theRange];
            break; // Could set n = 1000 which would also break...
        }
    }


    return number;
}
于 2013-02-06T20:34:43.917 に答える
0

これを解決するために、NSNumbers の NSArray も使用しました。フィボナッチ数の桁を逆順に格納すると、使用するコードを大幅に減らすことができます。

両方の NSArray がフィボナッチ数を表す 2 つの引数を持つメソッドを作成し、次の数を表す NSArray を返します。したがって、89 と 144 を加算して 13 番目のフィボナッチ数を計算するには、メソッドの 2 つの引数の値が [9, 8] & [4, 4, 1] であり、[3, 3, 2] を返します。

この方法で「持ち運び」する方が簡単だと思います。天才数学者なら、これを紙の上で解く方法もあるらしい。

于 2013-02-02T20:41:58.480 に答える