Detect break statement in function? - objective-c

I have the function below:
- (void)doStuff {
BOOL allDoneNow = NO;
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest) {
allDoneNow = YES;
break;
}
}
if (allDoneNow) break;
}
}
Now, if I call that method with [self doStuff];, how can I detect if the function broke? Or is there a better way to stop and restart the execution of a function?

- (BOOL)doStuff // <- return a boolean value
{
for (int i = 0; i < [arABFBmatches count]; i++)
{
for (int j = 0; j < [arABFBmatches count]; j++)
{
if (should_skip_rest)
{
return NO; // <- NO for break
}
}
}
return YES; // <- YES for completed
}
This beaks the execution of the function. If you want to restart it, simply call it in a while loop.
while( (doStuff()==NO) && thereShouldBeAnotherConditionForStopping )
{
// Do something after each attempt, otherwise it seems to be a little bit silly
}

Or you can use blocks, like this:
- (void)doStuff:(void (^)())breakBlock{
BOOL allDoneNow = NO;
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest) {
allDoneNow = YES;
breakBlock();
break;
}
}
if (allDoneNow) breakBlock();
}
}
and call it:
[self doStuff:^{
NSLog(#"ends with break");
}];

Related

Objective-C equal distribution from 5 different NSMutableArrays

This is my code but its still not correct. Currently i can distribute like this: 0,1,2,0,1,2,0,1,2 but i will distribute it 0,1,2,2,1,0,0,1,2,2 (0,1,2 are the groups)
//Create x Groups
for (int z=0; z<numberOfGroups; z++) {
mutableArrayOfSubarrays[z] = [NSMutableArray arrayWithCapacity:countOfElementsForTheGroups];
}
int nextSubarray = 0;
//Distribute the Objects into the groups
for (int i = 0; i < [AllObjectsToDistribute count]; i++)
{
[mutableArrayOfSubarrays[nextSubarray] addObject:[AllObjectsToDistribute objectAtIndex:i]];
nextSubarray = nextSubarray % customGroups;
nextSubarray++;
nextSubarray = nextSubarray % customGroups;
}
Keep track of which way the group index counts in a BOOL.
Example:
NSUInteger groupIndex = 0;
BOOL groupIndexCountsUp = YES;
for (id object in allObjectsToDistribute) {
[groupsArray[groupIndex] addObject:object];
if (groupIndexCountsUp) {
if (groupIndex < numberOfGroups - 1)
groupIndex++;
else
groupIndexCountsUp = NO;
}
else {
if (groupIndex > 0)
groupIndex--;
else
groupIndexCountsUp = YES;
}
}

Generating primes List in objective C?

I create this objective C class to Genrate prime numbers from n to limit. I have problem I could not get the item in NSMutableArray inside for loop. can some one show me how can I fix it?
#implementation Prime
-(NSMutableArray *)generatePrimes:(int)upperLimit{
NSMutableArray *primes = [[NSMutableArray alloc]init];
bool isPrime;
int j;
[primes addObject:[NSDecimalNumber numberWithInt:2]];
for (int i= 3; i <= upperLimit ; i+=2) {
j = 0;
isPrime = YES;
NSInteger index;
for(id obj in primes)
{
index = [primes indexOfObject:obj];
if((index * index) <= i )
{
if(i % index == 0)
{
isPrime = NO;
break;
}
}
}
if(isPrime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
#end
This question is a little vague, but it seems to me what you're trying to do is convert the NSDecimalNumber back into an int. What your code is actually doing is getting the number's index inside the array (ie the first object is 0, the second is 1, etc.) If you are trying to get the original value of i, change these lines:
for(id obj in primes)
{
index = [primes indexOfObject:obj];
to this:
for(NSDecimalNumber num in primes)
{
index = [num integerValue];
I'd also recommend using a different name than index, as that's misleading as to what you're actually doing.
-(NSMutableArray *)generatePrimes:(int)upperLimit
{
NSMutableArray *primes = [[NSMutableArray alloc]init];
bool isPrime;
for (int i=2; i<upperLimit; i++)
{
bool prime = true;
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
{
prime = false;
break;
}
}
if(prime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
or
-(NSMutableArray *)generatePrimes:(int)upperLimit
{
NSMutableArray *primes = [[NSMutableArray alloc]init];
[primes addObject:[NSDecimalNumber numberWithInt:2]];
for(int i=3; i < upperLimit; i++)
{
bool prime=true;
for(int j=0;j<primes.count && (((NSDecimalNumber *)primes[j]).integerValue*((NSDecimalNumber *)primes[j]).integerValue) <= i;j++)
{
if(i % (((NSDecimalNumber *)primes[j]).integerValue) == 0)
{
prime=false;
break;
}
}
if(prime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
Hope this helps!

Anagram algorithm objective C

i have written the following code to check anagram want to know is this perfect & is there any better way to implement the same in objective C
-(BOOL) findAnagram :(NSString *) string1 :(NSString *) string2
{
int len = string1.length;
if (len != string2.length)
{
return false;
}
for (int i=0; i < len; i++)
{
int h = 0;
int q = 0;
for (int k = 0; k < len ; k ++)
{
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k])
{
h++;
}
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k])
{
q++;
}
}
if (h!=q)
{
return false;
}
}
return TRUE;
}
A better performing version than yours, which is a O(n ^ 2) algorithm, is a O(n) algorithm:
BOOL anagrams(NSString *a, NSString *b)
{
if (a.length != b.length)
return NO;
NSCountedSet *aSet = [[NSCountedSet alloc] init];
NSCountedSet *bSet = [[NSCountedSet alloc] init];
for (int i = 0; i < a.length; i++)
{
[aSet addObject:#([a characterAtIndex:i])];
[bSet addObject:#([b characterAtIndex:i])];
}
return [aSet isEqual:bSet];
}
You want to know if two strings contain exactly the same characters? Easiest way would probably be to sort both of them and compare the sorted version.
Another way would be to count the number of appearances of each letter (how many As, how many Bs, and so forth), then compare those counts.
(Note: The second way is just a variation of the first one, it's one efficient way to sort a string)
It looks fine to me. But the code style is slightly odd. I would write it like this:
- (BOOL)isStringAnagram:(NSString *)string1 ofString:(NSString *)string2 {
int len = string1.length;
if (len != string2.length) {
return NO;
}
for (int i=0; i < len; i++) {
int h = 0;
int q = 0;
for (int k = 0; k < len; k++) {
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k]) {
h++;
}
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k]) {
q++;
}
}
if (h != q) {
return NO;
}
}
return YES;
}
The main issue I have is with the method name. While it's possible to have parameters that have nothing before them in the name, it is not advisable. i.e. you had findAnagram:: as the name whereas I've used isStringAnagram:ofString:.
This is an implementation on #zmbq suggestion of sorting and comparing.
You should consider the requirements of deleting spaces and being case insensitive.
- (BOOL)isAnagram:(NSString *)leftString and:(NSString *)rightString {
NSString *trimmedLeft = [[leftString stringByReplacingOccurrencesOfString:#" " withString:#""] lowercaseString];
NSString *trimmedRight = [[rightString stringByReplacingOccurrencesOfString:#" " withString:#""] lowercaseString];
return [[self stringToCharArraySorted:trimmedLeft] isEqual:[self stringToCharArraySorted:trimmedRight]];
}
- (NSArray *)stringToCharArraySorted:(NSString *)string {
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0 ; i < string.length ; i++) {
[array addObject:#([string characterAtIndex:i])];
}
return [[array sortedArrayUsingSelector:#selector(compare:)] copy];
}
called like this
BOOL isAnagram = [self isAnagram:#"A BC" and:#"cba"];
Check the following method which check Anagram strings.
-(BOOL)checkAnagramString:(NSString*)string1 WithAnotherString:(NSString*)string2{
NSCountedSet *countSet1=[[NSCountedSet alloc]init];
NSCountedSet *countSet2=[[NSCountedSet alloc]init];
if (string1.length!=string2.length) {
NSLog(#"NOT ANAGRAM String");
return NO;
}
for (int i=0; i<string1.length; i++) {
[countSet1 addObject:#([string1 characterAtIndex:i])];
[countSet2 addObject:#([string2 characterAtIndex:i])];
}
if ([countSet1 isEqual:countSet2]) {
NSLog(#"ANAGRAM String");
return YES;
} else {
NSLog(#"NOT ANAGRAM String");
return NO;
}
}
Another run of the mill algorithm:
- (BOOL) testForAnagramWithStrings:(NSString *)stringA andStringB: (NSString *)stringB{
stringA = [stringA lowercaseString];
stringB = [stringB lowercaseString];
int counter = 0;
for (int i=0; i< stringA.length; i++){
for (int j=0; j<stringB.length;j++){
if ([stringA characterAtIndex:i]==[stringB characterAtIndex:j]){
counter++;
}
}
}
if (counter!= stringA.length){
return false;
}
return true;
}

Dynamic two dimensional C array crashing in Objective-C

I am making a curve fitting program using matrices in the form of a two dimensional arrays but the compiler throws out BAD_ACCESS errors at random such as Thread 1:EXC_BAD_ACCESS (code=1, address=0x13f800000). The program works sometimes and other times crashes. Any ideas would be appreciated. Thanks.
- (void)main {
NSLog(#"Enter size");
scanf("%i", &matrixSize);
float* temp;
matrix = (float**)calloc(matrixSize, sizeof(float*));
temp = (float*)calloc(matrixSize+1, sizeof(float));
for (int i = 0; i < matrixSize+1; i++) {
matrix[i] = temp + (i*(matrixSize+1));
}
[self enterPoints];
[self elimination];
[self setNeedsDisplay:YES];
free(matrix);
free(temp);
}
//points entered here
- (void)enterPoints {
CGPoint *points = (CGPoint *)malloc(matrixSize * sizeof(CGPoint));
for (int i = 0; i < matrixSize; i++) {
scanf("%lf", &points[i].x);
scanf("%lf", &points[i].y);
}
for (int j = 0; j < matrixSize; j++) {
for (int i = 0; i < matrixSize+1; i++) {
if (i == (matrixSize)) {
matrix[i][j] = points[j].y;
}
else {
matrix[i][j] = pow(points[j].x, (matrixSize-1)-i);
}
}
}
free(points);
}
//matrix reduction occurs here
- (void)elimination {
for (int j = 0; j < matrixSize; j++) {
double divideValue = matrix[j][j];
for (int i = 0; i < matrixSize+1; i++) {
matrix[i][j] /= divideValue;
}
for (int j1 = 0; j1 < matrixSize; j1++) {
if (j1 == j) {
if (j1 == matrixSize-1) {
break;
}
else {
j1++;
}
}
double subValue = matrix[j][j1];
for (int i = 0; i < matrixSize+1; i++) {
matrix[i][j1] -= matrix[i][j]*subValue;
}
}
}
}
//drawing the polynomial
- (void)drawRect:(NSRect)dirtyRect {
NSGraphicsContext * GraphicsContext = [NSGraphicsContext currentContext];
CGContextRef context = (CGContextRef) [GraphicsContext graphicsPort];
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
CGContextSetLineWidth(context, 3.0);
CGContextMoveToPoint(context, 0, matrix[matrixSize][0]*100 + 100);
[GraphicsContext saveGraphicsState];
CGMutablePathRef path;
path = CGPathCreateMutable();
for (float i = -matrixSize; i < matrixSize; i+=.01) {
float y = 0;
for (int j = 0; j < matrixSize; j++) {
y += matrix[matrixSize][j]*pow(i, j);
}
CGContextAddLineToPoint(context, i*100 + 100, y*100 + 100);
}
CGContextStrokePath(context);
[GraphicsContext restoreGraphicsState];
}
You did not allocate enough memory for your matrix. This line sets up the entire data area, but you have only allocated matrixSize+1 elements, instead of matrixSize*(matrixSize+1):
temp = (float*)calloc(matrixSize+1, sizeof(float));
So, maintaining the matrixSize+1 columns and matrixSize rows:
matrix = (float**)calloc(matrixSize, sizeof(float*));
temp = (float*)calloc(matrixSize * (matrixSize+1), sizeof(float));
for (int i = 0; i < matrixSize; i++) {
matrix[i] = temp + (i*(matrixSize+1));
}
When you use this later, be careful. You are addressing it wrong:
for (int j = 0; j < matrixSize; j++) {
for (int i = 0; i < matrixSize+1; i++) {
if (i == (matrixSize)) {
matrix[i][j] = points[j].y;
}
else {
matrix[i][j] = pow(points[j].x, (matrixSize-1)-i);
}
}
}
Notice that i goes to matrixSize+1 but you are using that as the row index (there are only matrixSize rows). I think you meant to use matrix[j][i] instead of matrix[i][j]. You also do this when you construct the initial matrix, but I've actually changed that to be in line with your allocation.
So there are two points of buffer overrun in your program that I see.
EXC_BAD_ACCESS indicates one of your objects is being over-released (not to be confused with garbage collection) before invoking a method on it. Once you reach the point in your code where you invoke the method on the collected object, the pointer is referencing an invalid memory location.
To find Zombie objects have a look at this: How to Enable NSZombie in XCode
I've used this and it works very well.

Defining a matrix as an array of arrays and computation its inverse matrix in C++

Unfortunately I haven't much experience in C++ and I'm trying to progress myself in C++.
Firstly,I defined array of arrays so that I formed an 3x3 matrix:
array< array< double >^ >^ input = gcnew array< array< double >^ >(3);
for (j=0;j<input->Length;j++){
input[j]=gcnew array<double>(3);
Then I assigned matrix elements to input array of arrays:
int value=1;
for(y=0;y<(3);y++){
for(x=0;x<(3);x++)
{input[y][x]=value;
value=value+1;
}
}
Is there a C++ function that compute inverse matrix of this input array of arrays?
Could you help me please?
Best Regards...
Look at Simple 3x3 matrix inverse code (C++).
There are no functions in C++ to make matrix operations, you'll need to find some library to do it or implement your own.
Note that for fixed size arrays, you can use regular C/C++ arrays, like this one:
double arr[3][3];
Wikipedia has a list of numerical libraries in various programming languages. If the functions that you are looking for are not available you could also consider writing a wrapper function around an available Fortran or C or C++ implementation.
There is not built in C++ function to do matrix inversion (or for any other matrix calculations).
There are lots of methods for matrix inversion mentioned HERE.
If you want efficiency and ease of implementation then Guassian Elimination is
probably the best.
Code for inverse of matrix using Elementary row transformation in c++
#include<iostream>
#include<stdio.h>
#include<conio.h>
using
namespace std;
float a[4][4];float b[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
int no = 4;
int check(int k) {
float cont = 0, cont2 = 0;
for (int i = k; i < no; i++) {
if (a[i][k] == 1) {
for (int j = 0; j < no; j++) {
cont = a[i][j];
cont2 = b[i][j];
a[i][j] = a[k][j];
b[i][j] = b[k][j];
a[k][j] = cont;
b[k][j] = cont2;
}
} else if (a[i][k] == 0) {
for (int j = 0; j < no; j++) {
cont = a[i][j];
cont2 = b[i][j];
a[i][j] = a[no - 1][j];
b[i][j] = b[no - 1][j];
a[no - 1][j] = cont;
b[no - 1][j] = cont2;
}
}
}
return 0;
}
int divi(int k) {
float particular = a[k][k];
for (int i = 0; i < no; i++) {
a[k][i] = a[k][i] / particular;
b[k][i] = b[k][i] / particular;
if (a[k][i] == (-0)) {
a[k][i] = 0;
}
if (b[k][i] == (-0)) {
b[k][i] = 0;
}
}
return 0;
}
int sub1(int k) {
float particular;
for (int j = k + 1; j < no; j++) {
particular = a[j][k];
for (int i = 0; i < no; i++) {
a[j][i] = a[j][i] - (particular * a[k][i]);
b[j][i] = b[j][i] - (particular * b[k][i]);
if (a[j][i] == (-0)) {
a[j][i] = 0;
}
if (b[j][i] == (-0)) {
b[j][i] = 0;
}
}
}
return 0;
}
int sub2(int k) {
float particular;
for (int j = k - 1; j >= 0; j--) {
particular = a[j][k];
for (int i = no - 1; i >= 0; i--) {
a[j][i] = a[j][i] - (particular * a[k][i]);
b[j][i] = b[j][i] - (particular * b[k][i]);
if (a[j][i] == (-0)) {
a[j][i] = 0;
}
if (b[j][i] == (-0)) {
b[j][i] = 0;
}
}
}
return 0;
}
int disp(){
cout<<endl;
for(int x=0;x<no;x++){
for(int y=0;y<no;y++){
if(a[x][y]==(-0)){a[x][y]=0;}
if(b[x][y]==(-0)){b[x][y]=0;}
printf("%0.1f|||%0.1f ",a[x][y],b[x][y]);
}
cout<<endl;}
}
int main()
{
for(int i=0;i<no;i++){
for(int j=0;j<no;j++){cout<<"Enter a["<<i<<"]["<<j<<"]";cin>>a[i}[j];}
}
for(int i=0;i<no;i++){
for(int j=0;j<no;j++){cout<<a[i][j]<<" ";}
cout<<endl;
}
for(int i=0;i<no;i++){
check(i);
disp();
divi(i);
disp();
sub1(i);
disp();
}
for(int i=no-1;i>=0;i--){
sub2(i);
disp();
cout<<endl;
}
getch();
getch();
getch();
return 0;}
}