views:

211

answers:

3

Problem : Take an integer as input and print out number equivalents of each number from input. I hacked my thoughts to work in this case but I know it is not an efficient solution.

For instance :

110

Should give the following o/p : 

one
one 
zero

Could someone throw light on effective usage of Arrays for this problem?

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int input, i=0, j,k, checkit;
    int temp[i];

    NSLog(@"Enter an integer :");
    scanf("%d", &input);
    checkit = input;

    while(input > 0)
    {
        temp[i] = input%10;
        input = input/10;
        i++;
    }

    if(checkit != 0)
    {
    for(j=i-1;j>=0;j--)
    {
        //NSLog(@" %d", temp[j]);
        k = temp[j];
        //NSLog(@" %d", k);

        switch (k) {

            case 0:
                NSLog(@"zero");
                break;
            case 1:
                NSLog(@"one");
                break;
            case 2:
                NSLog(@"two");
                break;
            case 3:
                NSLog(@"three");
                break;
            case 4:
                NSLog(@"four");
                break;
            case 5:
                NSLog(@"five");
                break;
            case 6:
                NSLog(@"six");
                break;
            case 7:
                NSLog(@"seven");
                break;
            case 8:
                NSLog(@"eight");
                break;
            case 9:
                NSLog(@"nine");
                break;

            default:
                break;
        }

    }
    }
    else
        NSLog(@"zero");

    [pool drain];
    return 0;
}
A: 

I'd start by setting up this initializer:

NSArray* myArray = [NSArray arrayWithObjects: @"zero", @"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", @"nine", nil];

Feldur
I was referring to arrays for the individual digits of the input number. Thank you..
ThinkCode
@NJTechie: Unnecessary. You can get the individual digits using the modulo (%) operator.
Noah Witherspoon
Since this array is fixed and initialised wholly from constant string expressions (for which normal retain/release memory management is superfluous) you could probably make an argument for using a standard C array rather than NSArray.
walkytalky
@Noah : That is what I dd but I have to store the digits and print them backwards to achieve the solution.
ThinkCode
A: 

Of course it's unnecessary, but his question was arrays, not re-parse the problem.

As far as NGTechie's reply, I now don't understand what you're trying to do. Clarify?

Feldur
Use comments to reply to your answer or edit your answer to add more information. Do not add another answer. This is not a forum.
Shaggy Frog
I want to dynamically initialize the array and store each digit for the input number in an array and then print the array backwards to solve the problem. What I implemented is a hack/quick fix. Initializing array to zero and then taking first element off for the solution to work...
ThinkCode
+2  A: 

There are a number of ways to achieve what you want. Since you're talking about dynamic arrays, the obvious thing to do would be to use the foundation class NSMutableArray to build your stack of digits, although this does have the disadvantage of requiring a little dance through NSNumber to store and retrieve:

static NSString names[] = { @"zero", @"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", @"nine" };
NSMutableArray* digits = [[NSMutableArray alloc] initWithCapacity:10] // arbitrary initial capacity
while ( input > 0 )
{
    [digits insertObject:[NSNumber numberWithInt:input%10] atIndex:0];
    input /= 10;
}

if ( [digits count] )
{
    for ( int i = 0; i < [digits count]; ++i )
    {
        NSLog(@"%@", names[[[digits objectAtIndex:i] intValue]]);
    }
}
else
{
    NSLog(@"zero");
}

[digits release];

Otherwise, you could use a C array, but rather than initialising the array to zero length (which really seems like a Bad Idea), you could initialise it to the maximum capacity you will ever need, to wit: the number of digits of the biggest int. This may vary depending on the word length you're compiling for, but you can determine that before you compile. A 32 bit int can be up to 10 digits long; a 64 bit 20. The code then is reasonably similar:

int digits[20];  // hard coded array size constants are evil, of course
int last = 0;
while ( input > 0 )
{
    digits[last++] = input % 10;
    input /= 10;
}

if ( last )
{
    while ( last --> 0 )
    {
        NSLog ( @"%@", names[digits[last]] );
    }
}
else
{
    NSLog(@"zero");
}

This approach is superficially simpler, but certainly more error prone. (Indeed, since I haven't run this code there are almost guaranteed to be errors in it!)

Another way to do this is to sleaze around the problem altogether and use sprintf to extract the digits in the right order:

char digits[21]; // hard coded array size constants are *still* evil
sprintf(digits, "%d", input);
int ptr = 0;
while ( digits[ptr] )
{
    NSLog(@"%@", names[digits[ptr++]]);
}

if ( ptr == 0 )
{
    NSLog(@"zero");
}

This probably counts as cheating, though.

Note that scanf will handle a leading minus sign in the input, so the input number may be negative; dealing with this situation is left as an exercise.

walkytalky
Thanks for the different solutions. I was wondering if we can dynamically set the array size during the course of the program flow rather than using initwithcapacity (10) or 20 or 21 in the next 2 examples. The code itself makes lot of sense, I am sure it works, just the array initialization dynamically since we are talking about resource challenged iPhone in the long run!
ThinkCode
With NSMutableArray, you can set the initial capacity to 1 if you want -- it'll resize automatically as you add stuff to it, but there's a cost to expansion so using a reasonable initial capacity is somewhat helpful. With C arrays you're pretty much stuck with whatever you specify up front, barring some tedious reallocation and copying. But if 21 ints are going to make or break your application you've got much bigger problems. I don't know, but I'd guess the overhead for an NSMutableArray instance is more than that -- throw in the NSNumber cost as well and those 21 ints are looking golden...
walkytalky
(I'd still recommend the NSMutableArray approach, though, on the grounds of safety. As I say, the cost of pretty much everything else in your app will be much higher than a few bytes of array.)
walkytalky
(Come to think of it, ISTR reading elsewhere on SO that NSNumbers up to 12 are preallocated and shared. So the cost for those should be essentially nothing -- just an int-sized pointer.)
walkytalky
You nailed it with your explanation! NSMutableArray it is then! Thank you!
ThinkCode