Cocoa Touch - Comparing Ints - cocoa-touch

I have a maybe simple problem. I am going to generate 3 random numbers ranging from 0 to 2 and I want to determine if there are any duplicates.
Any ideas?

if (num1 == num2) {
}
else if (num1 == num3) {
}
else if (num2 == num3) {
}
else {
//There are no dups.
}
Checks if there is a duplicate.
if (num1 == num2) {
counter++;
}
if (num1 == num3) {
counter++;
}
if (num2 == num3) {
counter++;
}
This finds how many duplicates there are (for an added bonus).
EDIT:
For x amount of numbers you might want to do this (using 10 as my example amount of ints):
int counter = 0;
int i[10] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
for (int g = 0; g < 10; g++)
{
for (int j = g+1; j < 10; j++)
{
if(i[g] == i[j])
{
counter++;
printf(#"%d\n", counter);
//If this if statement is true then there is a dup... In this case none are found.
}
}
}

How about this?
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
if ([occurenceDict objectForKey:number] == nil) {
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
occOfNum++;
}
}
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d times", [key intValue], [occurrences intValue]);
}
[randomNumbers release];
[occurenceDict release];
Output:
Number 0 is contained 1 times
Number 1 is contained 2 times
Number 2 is contained 1 times
Edit: Incase you want to know how this works, here is the same version but with comments to help you understand it:
// Create array with the numbers that we have randomly generated
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
// If this number has not been added to the dictionary
if ([occurenceDict objectForKey:number] == nil) {
// Add it
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
// Find how many times the number occurs with the "randomNumbers" array
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
// We found this number at this index, so increment the found count
occOfNum++;
}
}
// Save the number of times which "number" occurs in the dictionary for later
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
// Iterate through all items in the dictionary and print out the result
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d", [key intValue], [occurrences intValue]);
}
// Release alloc'ed memory
[randomNumbers release];
[occurenceDict release];

Crikey, these answers are long-winded! Put your random generated numbers into an NSIndexSet. Test the set before inserting a number and you'll know that the number is already present, and so is a dupe.

Related

Poker hand strength

I've programatically determined hand rankings as added below. However, the issue is - if per say, two players end up with a pair.. How do I determine the winner?
To each card object I've added a prime number value. Ace being 41 and deuce being 3 and the in betweens. I'm thinking of multiplying these values when the hand is determined and whoever has the highest is winning. I need help determining whether this is the correct approach.
+(BOOL)isFull:(NSArray*)cards {
Cards *card1 = [cards objectAtIndex:0];
Cards *card2 = [cards objectAtIndex:1];
Cards *card3 = [cards objectAtIndex:2];
Cards *card4 = [cards objectAtIndex:3];
Cards *card5 = [cards objectAtIndex:4];
if (([card1.face isEqualToString:card3.face] && [card4.face isEqualToString:card5.face]) || ([card1.face isEqualToString:card2.face] && [card3.face isEqualToString:card5.face])) {
return true;
}
return false;
}
+(BOOL)isFlush:(NSArray*)cards {
NSMutableArray *organizedBySuit = [self organizeCardsSuitOrder:cards];
Cards *card1 = [organizedBySuit objectAtIndex:0];
Cards *card2 = [organizedBySuit objectAtIndex:4];
if ([card1.suit isEqualToString:card2.suit]) { return true; } else { return false; } // cards are organized by suit, so if the first equals the last..
}
+(BOOL)isStraight:(NSArray*)cards {
Cards *card1 = [cards objectAtIndex:0];
Cards *card2 = [cards objectAtIndex:1];
Cards *card3 = [cards objectAtIndex:2];
Cards *card4 = [cards objectAtIndex:3];
Cards *card5 = [cards objectAtIndex:4];
if ((card1.rankByInt) == 0 && (card2.rankByInt) == 9 && (card3.rankByInt) == 10 && (card4.rankByInt) == 11 && (card5.rankByInt) == 12) {
return true;
}
else if ((card1.rankByInt) < 9) {
if ((card2.rankByInt) == (card1.rankByInt) + 1) {
if ((card3.rankByInt) == (card1.rankByInt) + 2) {
if ((card4.rankByInt) == (card1.rankByInt) + 3) {
if ((card5.rankByInt) == (card1.rankByInt) + 4) {
return true;
}
}
}
}
}
return false;
}
+(BOOL)isTrip:(NSArray*)cards {
NSArray *faces = [self returnArrayOfFaces];
__block int pairCounter = 0;
for (int i = 0; i < [faces count]; i++) {
for (int t = 0; t < [cards count]; t++) {
Cards *card = [cards objectAtIndex:t];
if ([card.face isEqualToString:faces[i]]) {
pairCounter++;
}
}
if (pairCounter > 2) {
return true;
}
pairCounter = 0;
}
return false;
}
+(BOOL)isTwoPair:(NSArray*)cards {
NSArray *faces = [self returnArrayOfFaces];
__block int pairCount = 0;
__block int doublePairCount = 0;
for (int i = 0; i < [faces count]; i++) {
for (int t = 0; t < [cards count]; t++) {
Cards *card = [cards objectAtIndex:t];
if ([card.face isEqualToString:faces[i]]) {
pairCount++;
}
}
if (pairCount > 1) {
doublePairCount++;
}
pairCount = 0;
}
if (doublePairCount > 1) {
return true;
}
return false;
}
+(BOOL)isPair:(NSArray*)cards {
NSArray *faces = [self returnArrayOfFaces];
__block int pairCounter = 0;
for (int i = 0; i < [faces count]; i++) {
for (int t = 0; t < [cards count]; t++) {
Cards *card = [cards objectAtIndex:t];
if ([card.face isEqualToString:faces[i]]) {
pairCounter++;
}
}
if (pairCounter > 1) {
return true;
}
pairCounter = 0;
}
return false;
}
And the cards are generated to include their primes here.
+(NSMutableArray*)createDeck:(id)sender {
[sender removeAllObjects];
NSArray *faces = [[NSArray alloc] initWithObjects:#"A",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"J",#"Q",#"K", nil];
NSArray *suits = [[NSArray alloc] initWithObjects:#"h",#"d",#"c",#"s", nil];
NSArray *primes = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:41],[NSNumber numberWithInt:2],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5],[NSNumber numberWithInt:7],[NSNumber numberWithInt:11],[NSNumber numberWithInt:13],[NSNumber numberWithInt:17],[NSNumber numberWithInt:19],[NSNumber numberWithInt:23],[NSNumber numberWithInt:29],[NSNumber numberWithInt:31],[NSNumber numberWithInt:37], nil];
for (int i = 0; i < 52; i++) {
Cards *card = [[Cards alloc]init];
card.face = [NSString stringWithFormat:#"%#", faces[i % 13]];
card.suit = [NSString stringWithFormat:#"%#", suits[i / 13]];
card.rankByInt = i % 13;
card.symbol = [Cards symbolForSuit:card.suit];
card.prime = [[primes objectAtIndex:(i % 13)] intValue];
[sender addObject:card];
}
[sender shuffle];
return sender;
}
So if possible can you provide me with the way to go forward to essentially 'rank' each hand by the cards values after I have retrieved their rank such as flush, straight etc..
Also, if you see any ways to improve the efficiency of my checks for hand ranks, please share.
First evaluate the hand type. If those are equal, compare the highest card that makes up the hand (unless it's a full house, then compare the set). If all cards in the hand type are equal, and the hand type is less than 5 cards, compare the next highest card in the 5 card hand. Only if the best combination of 5 cards are equal between two hands do the hands tie.
I wrote a poker hand generator and strength comparer in python that may be of some interest to you: https://github.com/Alec-ala/poker-stud-showdown

array index out of bounds problems

So I'm making a biginteger program, and I'm having a problem with adding two arrays that aren't the same length. The problem I'm having is with the add method. If I'm iterating through an array is there any way to test if element is out of bounds. I've tried testing if the element in a is equal to nil, but I still get the exception. Any help would be great thanks.
#import <Foundation/Foundation.h>
#import "MPInteger.h"
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
- (MPInteger *) add: (MPInteger *) x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSInteger arrayCount;
if (a < b) {
arrayCount = [b count];
} else {
arrayCount = [a count];
}
int num = 10;
int carry = 1;
NSNumber *total;
NSNumber *carrySum;
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
for (NSInteger j = [c count]-1; j >=0; j--) {
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - num);
carrySum = #([c[j-1] intValue] + carry);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
}
}
NSString *str = [c componentsJoinedByString:#""];
NSLog(#"%#", str);
return x;
}
-(MPInteger *) multiply: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSMutableArray *sum = [NSMutableArray array];
NSNumber *total;
NSNumber *carrySum;
int num = 10;
NSNumber *endZero = 0;
NSInteger bottomCount = [b count]-1;
while (bottomCount != -1) {
for (int i = 0; i < [a count]; i++) {
total = #([a[i] intValue] * [[b objectAtIndex:bottomCount] intValue]);
if (bottomCount == [b count] -1) {
[c addObject:total];
} else {
[c replaceObjectAtIndex:i withObject:total];
}
}
for (NSInteger j = [c count]-1; j>=0; j--) {
NSString *carry = [NSString stringWithFormat:#"%d", [c[j] intValue]];
NSString *carry2 = [carry substringToIndex:1];
int carryFinal = [carry2 intValue];
NSString *carry3 = [carry2 stringByAppendingString:#"0"];
int carry4 = [carry3 intValue];
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - carry4);
carrySum = #([c[j-1] intValue] + carryFinal);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
} else {
if(j == 0) {
if (bottomCount == [b count] -1) {
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
} else {
[c addObject:#([endZero intValue])];
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
}
}
}
}
}
NSMutableArray *finalSum = [NSMutableArray array];
MPInteger *ele1;
MPInteger *ele2;
MPInteger *eleSum;
NSNumber *endZ= #(0);
[finalSum insertObject:endZ atIndex:0];
for (int k = 0; k < [sum count]; k++) {
NSString *str= [NSString stringWithFormat:#"%d", [sum[k] intValue]];
NSString *str2 = [NSString stringWithFormat:#"%d", [sum[k+1] intValue]];
ele1 = [[MPInteger alloc] initWithString:str];
ele2 = [[MPInteger alloc] initWithString:str2];
eleSum = [ele1 add: ele2];
NSLog(#"%#", eleSum);
}
NSLog(#"%#", sum);
return self;
}
Updated this
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
has now become:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
NSLog(#"%#", c[idx]);
}];
What I think I need to do is every index that is in array a and not b or vise versa, is add beginning zeros, but I don't know how to do that.
I printed out what it does after each iteration and it gives:
2013-09-02 12:31:42.630 Asgn1[42471:303] 5
2013-09-02 12:31:42.632 Asgn1[42471:303] 3
2013-09-02 12:31:42.632 Asgn1[42471:303] 1
And a final answer of:
2013-09-02 12:31:42.633 Asgn1[42471:303] 353
For the code that is failing would it not be simpler to take a mutableCopy of the large array and then loop over the smaller array for the calculations?
Perhaps something like this:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
}];

Check if string is palindrome in objective c

I'm trying to check if a string is palindrome or not using objective c. I'm new to programming without any experience in other programming languages so bear with me please. I get stuck at my if condition I want it to say that if the first position in the string is equal to the last one the string is a palindrome.
What im a doing wrong?
int main (int argc, const char * argv[])
{
NSString *p = #"121" ;
BOOL palindrome = TRUE;
for (int i = 0 ; i<p.length/2+1 ; i++)
{
if (p[i] != p [p.Length - i - 1])
palindrome = false;
}
return (0);
}
You're trying to use an NSString as an NSArray (or probably, like a C string), which won't work. Instead, you need to use the NSString method characterAtIndex: to get the character to test.
Apart from the unbalanced braces, accessing a character from NSString is more complicated than using array notation. You need to use the method characterAtIndex: You can optimise your code, by breaking out of the loop if a palindrome is impossible and taking the length call outside of the for loop.
NSString *p = #"121";
NSInteger length = p.length;
NSInteger halfLength = (length / 2);
BOOL isPalindrome = YES;
for (int i = 0; i < halfLength; i++) {
if ([p characterAtIndex:i] != [p characterAtIndex:length - i - 1]) {
isPalindrome = NO;
break;
}
}
It may be desirable to check case insensitively. To do this, make the string be all lowercase before looping, using the lowercaseString method.
As pointed out by Nikolai in the comments, this would only work for strings containing 'normal' unicode characters, which is often not true — such as when using UTF8 for foreign languages. If this is a possibility, use the following code instead, which checks composed character sequences rather than individual characters.
NSString *p = #"121";
NSInteger length = p.length;
NSInteger halfLength = length / 2;
__block BOOL isPalindrome = YES;
[p enumerateSubstringsInRange:NSMakeRange(0, halfLength) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
NSRange otherRange = [p rangeOfComposedCharacterSequenceAtIndex:length - enclosingRange.location - 1];
if (![substring isEqualToString:[p substringWithRange:otherRange]]) {
isPalindrome = NO;
*stop = YES;
}
}];
var str: NSString = "123321"
var length = str.length
var isPalindrome = true
for index in 0...length/2{
if(str.characterAtIndex(index) != str.characterAtIndex(length-1 - index)){
print("\(index )not palindrome")
isPalindrome = false
break
}
}
print("is palindrome: \(isPalindrome)")
As it seems there's no answer yet that handles composed character sequences correctly I'm adding my two cents:
NSString *testString = #"\u00E0 a\u0300"; // "à à"
NSMutableArray *logicalCharacters = [NSMutableArray array];
[testString enumerateSubstringsInRange:(NSRange){0, [testString length]}
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop)
{
[logicalCharacters addObject:substring];
}];
NSUInteger count = [logicalCharacters count];
BOOL isPalindrome = YES;
for (NSUInteger idx = 0; idx < count / 2; ++idx) {
NSString *a = logicalCharacters[idx];
NSString *b = logicalCharacters[count - idx - 1];
if ([a localizedCaseInsensitiveCompare:b] != NSOrderedSame) {
isPalindrome = NO;
break;
}
}
NSLog(#"isPalindrome: %d", isPalindrome);
This splits the string into an array of logical characters (elements of a string that a normal user would call a "character").
#import Foundation;
BOOL isPalindrome(NSString * str)
{
if (!str || str.length == 0) return NO;
if (str.length == 1) return YES;
for(unsigned i = 0; i < str.length / 2; ++i)
if ([str characterAtIndex:i] != [str characterAtIndex:str.length - i - 1]) return NO;
return YES;
}
int main() {
#autoreleasepool {
NSLog(#"%s", isPalindrome(#"applelppa") ? "YES" : "NO");
} return 0;
}
Recursive
- (BOOL)isPaliRec:(NSString*)str :(int)start :(int)end{
if(start >= end)
return YES;
else if([str characterAtIndex:start] != [str characterAtIndex:end])
return NO;
else
return [self isPaliRec:str :++start :--end];
}
Non Recursive
- (BOOL)isPali:(NSString*)str{
for (int i=0; i<str.length/2; i++)
if([str characterAtIndex:i] != [str characterAtIndex:(str.length-i-1)])
return NO;
return YES;
}
you can call:
NSString *str = #"arara";
[self isPaliRec:str :0 :(int)str.length-1];
[self isPali:str];
Swift 3:
// Recursive
func isPaliRec(str: String, start: Int = 0, end: Int = str.characters.count-1) -> Bool {
if start >= end {
return true
} else if str[str.index(str.startIndex, offsetBy: start)] != str[str.index(str.startIndex, offsetBy: end)] {
return false
} else {
return isPaliRec(str: str, start: start+1, end: end-1)
}
}
// Non Recursive
func isPali(str: String) -> Bool {
for i in 0..<str.characters.count/2 {
let endIndex = str.characters.count-i-1
if str[str.index(str.startIndex, offsetBy: i)] != str[str.index(str.startIndex, offsetBy: endIndex)] {
return false
}
}
return true
}
// Using
let str = "arara"
isPaliRec(str: str)
isPali(str: str)
Also, you can use swift 3 methods like a string extension... It's more elegant. extension sample
NSString *str=self.txtFld.text;
int count=str.length-1;
for (int i=0; i<count; i++) {
char firstChar=[str characterAtIndex:i];
char lastChar=[str characterAtIndex:count-i];
NSLog(#"first=%c and last=%c",firstChar,lastChar);
if (firstChar !=lastChar) {
break;
}
else
NSLog(#"Pailndrome");
}
We can also do this using NSRange like this...
enter code NSString *fullname=#"123321";
NSRange rangeforFirst=NSMakeRange(0, 1);
NSRange rangeforlast=NSMakeRange(fullname.length-1, 1);
BOOL ispalindrome;
for (int i=0; i<fullname.length; i++) {
if (![[fullname substringWithRange:rangeforFirst] isEqualToString:[fullname substringWithRange:rangeforlast]]) {
NSLog(#"not match");
ispalindrome=NO;
return;
}
i++;
rangeforFirst=NSMakeRange(i, 1);
rangeforlast=NSMakeRange(fullname.length-i-1, 1);
}
NSLog(#"no is %#",(ispalindrome) ? #"matched" :#"not matched");
NSString *str1 = #"racecar";
NSMutableString *str2 = [[NSMutableString alloc] init];
NSInteger strLength = [str1 length]-1;
for (NSInteger i=strLength; i>=0; i--)
{
[str2 appendString:[NSString stringWithFormat:#"%C",[str1 characterAtIndex:i]]];
}
if ([str1 isEqual:str2])
{
NSLog(#"str %# is palindrome",str1);
}
-(BOOL)checkPalindromeNumber:(int)number{
int originalNumber,reversedNumber = 0,remainder;
originalNumber=number;
while (number!=0) {
remainder=number%10;
reversedNumber=(reversedNumber*10)+remainder;
number=number/10;
}
if (reversedNumber==originalNumber) {
NSLog(#"%d is Palindrome Number",originalNumber);
return YES;
}
else{
NSLog(#"%d is Not Palindrome Number",originalNumber);
return NO;
}
}

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;
}