I am trying to sort 15 random numbers using Objective-C in the code shown below. The code is not working as planned. I took the concept from the the insertion sort C code. The 15 random numbers are generating properly but the sort is not working.
C code:
int i, j, index;
for (i = 1; i < array_size; ++i)
{
index = a[i];
for (j = i; j > 0 && a[j-1] > index; j--)
a[j] = a[j-1];
a[j] = index;
}
Objective-C code:
-(IBAction)clicked_insertsort:(id)sender
{
NSMutableArray *array = [NSMutableArray array];
for (int x = 0; x < 15; x++)
{
[array addObject: [NSNumber numberWithInt: arc4random()%200]];
}
NSLog(#"%#",array);
{
int i, j;
id index;
for (i = 1; i < 15; ++i)
{
index = [array objectAtIndex:(NSUInteger)i]; // a[i];
for (j = i; j > 0 && [array objectAtIndex:(NSUInteger)j-1] > index; j--)
[array replaceObjectAtIndex: (j) withObject: [array objectAtIndex: (j-1)]];
[array objectAtIndex:(NSUInteger)j] == index ;
}
}
NSLog(#"%#",array);
}
You are comparing pointers, which is just sorting your array by the memory addresses of your objects, not their actual value.
index = [array objectAtIndex:(NSUInteger)i]; // a[i];
[array objectAtIndex:(NSUInteger)j-1] > index
You need to get the primitive integer value of the NSNumber:
[NSNumber numberWithInt:20] != 20; // This is wrong.
[[NSNumber numberWithInt:20] intValue] == 20; // This is correct.
Here's your code, with revisions:
-(IBAction)clicked_insertsort:(id)sender
{
NSMutableArray *array = [NSMutableArray array];
for (int x = 0; x < 15; x++)
{
[array addObject: [NSNumber numberWithInt: arc4random()%200]];
}
NSLog(#"%#",array);
{
int i, j;
id index;
for (i = 1; i < 15; ++i)
{
index = [[array objectAtIndex:(NSUInteger)i] intValue]; // a[i];
for (j = i; j > 0 && [[array objectAtIndex:(NSUInteger)j-1] intValue] > index; j--)
[array replaceObjectAtIndex: (j) withObject: [array objectAtIndex: (j-1)]];
[[array objectAtIndex:(NSUInteger)j] intValue] == index ;
}
}
NSLog(#"%#",array);
}
Actually the problem is that the algorithm itself does not make much sense.
This line:
[array objectAtIndex:(NSUInteger)j] == index ;
Should be:
[array replaceObjectAtIndex:j withObject:index]; //yes again
Try this way, with modern syntax:
-(IBAction)clicked_insertsort:(id)sender
{
NSMutableArray *array = [NSMutableArray array];
for (int x = 0; x < 15; x++)
{
[array addObject: #(arc4random()%200)];
}
NSLog(#"%#",array);
NSUInteger i, j;
for (i = 1; i < 15; ++i)
{
NSNumber *current = array[i];
for (j = i; j > 0 && [array[j-1] unsignedIntegerValue] > [current unsignedIntegerValue]; j--)
array[j] = array[j-1];
array[j] = current;
}
NSLog(#"%#",array);
}
Run the code and see the result.
Related
What is the best algorithm to find all possible words from an array of array of character.
Here an example :
From this array : [[A],[B,C,D],[E,F],[G,H]]
I need in return an array of the 12 ordered possibilities [[A,B,E,G],[A,C,E,G], ... , [A,D,F,H]]
Do you know how to implement this algorithm ? If you know it and you provide an example in any language (C,JAVA,Javascript, ...), feel free to share because it's been a day I try to find it ...
Here how I tries to implement it ("array" is an array of array of char):
+ (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++) {
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}
It would be easiest to do this using a recursive method.
Java code
import java.util.Arrays;
public class CartesianProductCalculator {
private char[][] result;
private char[][] sets;
private char[] currentSet;
private int index;
public char[][] calculateProduct(char[][] sets) {
index = 0;
// calculate size of result
int resultSize = 1;
this.sets = sets;
for (char[] set : sets) {
resultSize *= set.length;
}
result = new char[resultSize][];
currentSet = new char[sets.length];
calculateProduct(sets.length-1);
return result;
}
// fills result from right to left
public void calculateProduct(int setIndex) {
if (setIndex >= 0) {
for (char c : sets[setIndex]) {
currentSet[setIndex] = c;
calculateProduct(setIndex-1);
}
} else {
result[index++] = Arrays.copyOf(currentSet, currentSet.length);
}
}
public static void main(String[] args) {
char[][] input = {{'A'},{'B','C','D'},{'E','F'},{'G','H'}};
CartesianProductCalculator productCalculator = new CartesianProductCalculator();
System.out.println(Arrays.deepToString(productCalculator.calculateProduct(input)));
}
}
Objectiv-C
+ (NSArray *) cartesianProductOfArrays(NSArray *arrays) {
int arraysCount = arrays.count;
unsigned long resultSize = 1;
for (NSArray *array in arrays)
resultSize *= array.count;
NSMutableArray *product = [NSMutableArray arrayWithCapacity:resultSize];
for (unsigned long i = 0; i < resultSize; ++i) {
NSMutableArray *cross = [NSMutableArray arrayWithCapacity:arraysCount];
[product addObject:cross];
unsigned long n = i;
for (NSArray *array in arrays) {
[cross addObject:[array objectAtIndex:n % array.count]];
n /= array.count;
}
}
return product;
}
C
#include <stdio.h>
#include <string.h>
void print(int size, char *array[size], int indexs[size]){
char result[size+1];
int i;
for(i = 0; i < size; ++i)
result[i] = array[i][indexs[i]];
result[size] = 0;
puts(result);
}
int countUp(int size, int indexs[size], int lens[size]){
int i = size -1;
while(i >= 0){
indexs[i] += 1;// count up
if(indexs[i] == lens[i])
indexs[i--] = 0;
else
break;
}
return i >= 0;
}
void find_all(int size, char *array[size]){
int lens[size];
int indexs[size];
int i;
for(i = 0; i < size; ++i){//initialize
lens[i] = strlen(array[i]);
indexs[i] = 0;
}
do{
print(size, array, indexs);
}while(countUp(size, indexs, lens));
}
int main(void){
char *array[] = { "A", "BCD", "EF", "GH" };
int size = sizeof(array)/sizeof(*array);
find_all(size, array);
return 0;
}
If you can remove duplicate entries in inner array objects before executing method then you won't get duplicate words in result array.
- (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++)
{
NSArray *cleanedArray = [[NSSet setWithArray:[array objectAtIndex:i]] allObjects];
[array replaceObjectAtIndex:i withObject:cleanedArray];
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}
I'm making an Objective C program to generate two random arrays and check them for similar numbers. I get the "NSRangeException" on the marked line of code, but I'm not sure why. Here's my code:
// Array Comparator (Check Two Arrays for Similar Numbers)
#interface ArrayComparator: NSObject
{
NSMutableArray *arrayOne;
NSMutableArray *arrayTwo;
}
- (void) generateFirstArray;
- (void) generateSecondArray;
- (void) check;
#end
#implementation ArrayComparator
- (void) generateFirstArray
{
arrayOne = [[NSMutableArray alloc] initWithCapacity: 50];
for (NSUInteger n = 0; n < 50; n++)
{
[arrayOne addObject: #(arc4random_uniform(999) + 1)];
}
for (NSUInteger n = 0; n < 50; n++)
{
printf("%li, ", (long) [arrayOne[n] integerValue]);
}
printf("first array.\n\n");
}
- (void) generateSecondArray
{
arrayTwo = [[NSMutableArray alloc] initWithCapacity: 50];
for (NSUInteger n = 0; n < 50; n++)
{
[arrayTwo addObject: #(arc4random_uniform(999) + 1)];
}
for (NSUInteger n = 0; n < 50; n++)
{
printf("%li, ", (long) [arrayTwo[n] integerValue]);
}
printf("second array.\n\n");
}
- (void) check
{
long similar = 0;
for (NSUInteger n = 0; n < 50; n++)
{
for (NSUInteger m = 0; m < 50; n++)
{
if ([arrayOne[n] integerValue] == [arrayTwo[m] integerValue]) // This is where I get the error.
{
similar++;
}
}
}
printf("There are %li similar numbers between the two arrays!", similar);
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool
{
ArrayComparator *arrayComp = [[ArrayComparator alloc] init];
[arrayComp generateFirstArray];
[arrayComp generateSecondArray];
[arrayComp check];
} return 0;
}
Any help is appreciated, thanks. (Please excuse my noobishness.)
(NSUInteger m = 0; m < 50; n++)
You mean m++.
I am trying to make an add method that works like long addition, so I want to start the addition from the end and work my way backwards so I can get the carrys right and etc. So I am currently trying to start working backwards over the array.
For example what im trying to do.
two arrays with the character 123456789
and i want to add them starting at 9 + 9 then move to 8+8
So I'm pretty sure I'm using the right way to iterate backwards over an array, but everytime I try I get just the runtime error, index out of bounds, and I can't figure out why. Any help would be great, I just cant figure out why it keeps throwing the exception.
-(MPInteger *) add: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
//for (int i = 0; i < [a count]; i++) {
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = [NSNumber numberWithInt:num];
NSNumber *total = [NSNumber numberWithInt:[[a objectAtIndex:i] intValue] + [[b objectAtIndex:i] intValue]];
if ([total intValue] >= [ourNum intValue]) {
total = [NSNumber numberWithInt:([total intValue] - [ourNum intValue])];
[c addObject:[NSNumber numberWithInt:([total intValue])]];
} else {
[c addObject:[NSNumber numberWithInt:[[a objectAtIndex:i] intValue]+[[b objectAtIndex:i] intValue]]];
}
NSLog(#"%#", c[i]);
}
return x;
}
First, let's clean up this code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = #(num);
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= [ourNum intValue]) {
total = #([total intValue] - [ourNum intValue]);
[c addObject:#([total intValue])];
} else {
[c addObject:#([a[i] intValue] + [b[i] intValue])];
}
NSLog(#"%#", c[i]);
}
return x;
}
Next, let's remove redundant/duplicate code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= num) {
total = #([total intValue] - num);
}
[c addObject:total];
NSLog(#"%#", c[i]);
}
return x;
}
Now we can clearly see all of the issues.
You're going from [a count] - 1 to 1. You should be going all the way to 0.
a and b might have different sizes, so if you only do [a count] - 1 to 0, then if for example [b count] < [a count], you'll get an index out of bounds error when you try to access b[i].
You're adding stuff to the end of c, but you should be adding it to the beginning of c since you're iterating backwards.
You don't store the carry anywhere.
You are accessing c[i], which doesn't exist.
You are starting with an empty array 'c', and you NSLog c[i] which is obviously out of bounds on the first iteration.
I have got a for loop, but can't access variable from outside the loop:
for (int i = 0, j = 0, k = 0, l = 0; i < [array1 count] && j < [array2 count] && k < [array3 count] && l < [array4 count]; i++ && j++ && k++ && l++)
{
NSDictionary *_myDict = [NSDictionary dictionaryWithObjectsAndKeys:[array1 objectAtIndex:i], #"Apples", [array2 objectAtIndex:j], #"Oranges", [array3 objectAtIndex:k], #"Grapes", [array4 objectAtIndex:l], #"Plums", nil];
}
Accessing it from inside works.
I tried it with singleton and instance method, it is still not accessible and always returns nil.
I would love to have global variable of it, but can't declare it inside the loop.
NSMutableArray *rows = [NSMutableArray array];
for (int i=0, j=0, k=0, l=0;
i < [array1 count] && j < [array2 count] && k < [array3 count] && l < [array4 count];
i++, j++, k++, l++)
{
NSMutableDictionary *row = [NSMutableDictionary dictionary];
[row setObject:[array1 objectAtIndex:i] forKey:#"Apples"];
[row setObject:[array2 objectAtIndex:j] forKey:#"Oranges"];
[row setObject:[array3 objectAtIndex:k] forKey:#"Grapes"];
[row setObject:[array4 objectAtIndex:l] forKey:#"Plums"];
[rows addObject:row];
}
Now connect your arrayController to rows array, set it's row class to NSMutableDictionary, and use #"Apples" etc in column bindings. Hope that solves it.
I want to display every factor of a number typed in a textfield to achieve this I tried using an array. But I am always getting the error 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]' . Any suggestions to eliminate this error?
NSMutableArray *array;
array = [NSMutableArray arrayWithCapacity:100];
for (factorsNumber=1; factorsNumber<=number; factorsNumber++) {
if (number%factorsNumber == 0) {
[array addObject:[NSString stringWithFormat:#"%d", factorsNumber]];
}
}
for (int i = 0; i <= [array count]; i++) {
factors.text = [NSString stringWithFormat:#"%d", i, [[array objectAtIndex:i] intValue]];
}
for (int i = 0; i <= [array count]; i++) {
should be
for (int i = 0; i <= [array count] - 1; i++) {
or
for (int i = 0; i < [array count]; i++) {
The valid indices of an n-element array are 0 to n-1.
In your for loop, remove the = so that it reads:
for (int i = 0; i < [array count]; i++)
you problem is here:
for (int i = 0; i < [array count]; i++) { // < instead of <=
factors.text = [NSString stringWithFormat:#"%d", i, [[array objectAtIndex:i] intValue]];
}