objective-c - 将对象插入 NSMutableArray 时出现意外行为

标签 objective-c cocoa nsmutablearray

所以我一直在研究 Objective-C 中的 Project Euler 问题 25,但我遇到了 NSDecimalNumber 的大小限制。 。因此,在尝试使用其他代码库后,我决定重新表示我的斐波那契数列,首先表示为 int 数组,然后表示为 NSNumberNSArray s。数组中的每个单元格都是一位数字。然后我可以将大数逐位相加,直到第 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;
}

有什么想法为什么我用它创建的 digitSumNSNumber 在需要携带时没有按预期存储?

最佳答案

正如上面提到的,我发现了我自己的错误以及其他几个错误。 insertObjectAtIndex 向 NSMutableArray 添加了一个全新的对象,而我想用 ReplaceObjectAtIndexWith 来替换之前的数字与新计算的数字。

XCode 刚刚更新,添加了从调试器查看 NSArray 内部的功能,正如我上面提到的,这会很好。这是两个 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;
}

关于objective-c - 将对象插入 NSMutableArray 时出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14664346/

相关文章:

objective-c - ASIHTTPRequest 错误不断出现

objective-c - 如何使用 Objective C 在 Cocoa 应用程序中异步获取数据

macos - 从 PlugIns 文件夹加载资源包

objective-c - 按字典键的值对包含NSMutableDictionary的NSMutableArray进行排序

ios - 如何过滤字典数组中的数据,每个字典都包含 NSSet 对象

json - 从 NSMutableArray 快速创建 jsonArray

iphone - 跳过带有委托(delegate)的 View Controller

objective-c - 将对象 ( UIViewController ) 转换到它们未知的子类

iphone - objective-c:将日期字符串转换为星期几+月份名称

objective-c - 将 OpenGL 与 Cocoa 结合使用的最佳方式是什么?