I have an NSMutableArray that I'd like to check for duplicate strings. I don't need to know what the strings are, just if there are any duplicates.
I'm thinking add the answers to an NSSet, then check to see if the number of entries is different than the original array. Is there a better way to do this?
Here is the code to see duplicates values
for(int j = 0; j < [myMutableArray count]; j++){
for( k = j+1;k < [myMutableArray count];k++){
NSString *str1 = [myMutableArray objectAtIndex:j];
NSString *str2 = [myMutableArray objectAtIndex:k];
if([str1 isEqualToString:str2])
NSLog(#"duplicate value is %#",[myMutableArray objectAtIndex:k]);
}
}
Related
I have on NSMutableArray like this:
NSMutableArray *array = [NSMutableArray arrayWithObjects:#"0",#"0",#"0",#"0",#"0", nil];
now I want check if all object in my array are to same and equal to 0 doing certain work!!!. but I don't know about this.
please guide me.
My friend try this:
NSMutableArray *array = [NSMutableArray arrayWithObjects:#"0",#"0",#"0",#"0",#"0", nil];
NSCountedSet *filter = [NSCountedSet setWithArray:array];
//this condition check number of 0 value with your array count
//if number of 0 equal to array count this means that all object in array is 0
if ([filter countForObject:#"0"] == [array count]) {
NSLog(#"all objects are 0");
}
You can use the usual for statement:
for (int i = 0; i < [array count]; i++)
{
NSString *string = [array objectAtIndex:i];
// Check for >0
}
Or fast enumeration:
for (NSString *string in array)
{
// Check for >0
}
I didn't fill on purpose the check part, considering that you are a iOS (i guess) beginner can i recommend a good book on iOS programming? iOS Programming: The Big Nerd Ranch Guide
In Xcode i am trying to make a graph into which some points (X,Y) are given by the user.The user can choose how many points he or she wants to plot on the graph. I have stored the X axis points in an NSMutableArray and the Y axis points in an NSMutableArray but now i need to sort these into ascending order so i can fix a bug with the graph when having two points with the same x or y axis plot. The NSMutableArrays contains primitive int's. An example of what i need to do is if i am given 4 coordinates for one of the axis such as 4,8,5,3 i need the array to be sorted into 3,4,5,8
The code below doesn't include the graph generation because it is quite long
Thanks for the help! -
int userInputCount;
printf("How many coordinates would you like to plot? ");
scanf("%i", &userInputCount);
printf("\n");
NSMutableArray * xCoordArray = [[NSMutableArray alloc] init];
NSMutableArray * yCoordArray = [[NSMutableArray alloc] init];
for (int i = 1; i <= userInputCount; i++){
int xCoord;
int yCoord;
printf("(%i) Enter coordinates [X,Y]: ", i);
scanf("%i,%i", &xCoord, &yCoord);
NSNumber *xCoordinate = [[NSNumber alloc] initWithInt:xCoord];
NSNumber *yCoordinate = [[NSNumber alloc] initWithInt:yCoord];
[xCoordArray addObject:xCoordinate];
[yCoordArray addObject:yCoordinate];
}
After working on it for a while I figured it out if anybody is trying the same thing
for (int j = 0; j < 2; j++){
for (int i = 0; i < [yCoordArray count] - 1; i++){
int yExchangeIntOne = [[yCoordArray objectAtIndex:i] intValue];
int yExchangeIntTwo = [[yCoordArray objectAtIndex:i +1] intValue];
if (yExchangeIntOne > yExchangeIntTwo){
[yCoordArray exchangeObjectAtIndex:i+1 withObjectAtIndex:i];
i = 0;
}
int xExchangeIntOne = [[xCoordArray objectAtIndex:i] intValue];
int xExchangeIntTwo = [[xCoordArray objectAtIndex:i +1] intValue];
if (xExchangeIntOne > xExchangeIntTwo){
[xCoordArray exchangeObjectAtIndex:i+1 withObjectAtIndex:i];
i = 0;
}
}
}
This goes right after the
[xCoordArray addObject:xCoordinate]; and the
[yCoordArray addObject:yCoordinate]; in the loop
For the Longest Common Subsequence of 2 Strings I have found plenty examples online and I believe that I understand the solution.
What I don't understand is, what is the proper way to apply this problem for N Strings? Is the same solution somehow applied? How? Is the solution different? What?
This problem becomes NP-hard when input has arbitrary number of strings. This problem becomes tractable only when input has fixed number of strings. If input has k strings, we could apply the same DP technique in by using a k dimensional array to stored optimal solutions of sub-problems.
Reference: Longest common subsequence problem
To find the Longest Common Subsequence (LCS) of 2 strings A and B, you can traverse a 2-dimensional array diagonally like shown in the Link you posted. Every element in the array corresponds to the problem of finding the LCS of the substrings A' and B' (A cut by its row number, B cut by its column number). This problem can be solved by calculating the value of all elements in the array.
You must be certain that when you calculate the value of an array element, all sub-problems required to calculate that given value has already been solved. That is why you traverse the 2-dimensional array diagonally.
This solution can be scaled to finding the longest common subsequence between N strings, but this requires a general way to iterate an array of N dimensions such that any element is reached only when all sub-problems the element requires a solution to has been solved.
Instead of iterating the N-dimensional array in a special order, you can also solve the problem recursively. With recursion it is important to save the intermediate solutions, since many branches will require the same intermediate solutions. I have written a small example in C# that does this:
string lcs(string[] strings)
{
if (strings.Length == 0)
return "";
if (strings.Length == 1)
return strings[0];
int max = -1;
int cacheSize = 1;
for (int i = 0; i < strings.Length; i++)
{
cacheSize *= strings[i].Length;
if (strings[i].Length > max)
max = strings[i].Length;
}
string[] cache = new string[cacheSize];
int[] indexes = new int[strings.Length];
for (int i = 0; i < indexes.Length; i++)
indexes[i] = strings[i].Length - 1;
return lcsBack(strings, indexes, cache);
}
string lcsBack(string[] strings, int[] indexes, string[] cache)
{
for (int i = 0; i < indexes.Length; i++ )
if (indexes[i] == -1)
return "";
bool match = true;
for (int i = 1; i < indexes.Length; i++)
{
if (strings[0][indexes[0]] != strings[i][indexes[i]])
{
match = false;
break;
}
}
if (match)
{
int[] newIndexes = new int[indexes.Length];
for (int i = 0; i < indexes.Length; i++)
newIndexes[i] = indexes[i] - 1;
string result = lcsBack(strings, newIndexes, cache) + strings[0][indexes[0]];
cache[calcCachePos(indexes, strings)] = result;
return result;
}
else
{
string[] subStrings = new string[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
if (indexes[i] <= 0)
subStrings[i] = "";
else
{
int[] newIndexes = new int[indexes.Length];
for (int j = 0; j < indexes.Length; j++)
newIndexes[j] = indexes[j];
newIndexes[i]--;
int cachePos = calcCachePos(newIndexes, strings);
if (cache[cachePos] == null)
subStrings[i] = lcsBack(strings, newIndexes, cache);
else
subStrings[i] = cache[cachePos];
}
}
string longestString = "";
int longestLength = 0;
for (int i = 0; i < subStrings.Length; i++)
{
if (subStrings[i].Length > longestLength)
{
longestString = subStrings[i];
longestLength = longestString.Length;
}
}
cache[calcCachePos(indexes, strings)] = longestString;
return longestString;
}
}
int calcCachePos(int[] indexes, string[] strings)
{
int factor = 1;
int pos = 0;
for (int i = 0; i < indexes.Length; i++)
{
pos += indexes[i] * factor;
factor *= strings[i].Length;
}
return pos;
}
My code example can be optimized further. Many of the strings being cached are duplicates, and some are duplicates with just one additional character added. This uses more space than necessary when the input strings become large.
On input: "666222054263314443712", "5432127413542377777", "6664664565464057425"
The LCS returned is "54442"
so I have a [NSMutableArray *paths] that contains UIBezierPaths that correspond to each separate path drawn on the screen. I also have another NSMutable array colors that contains the corresponding color for the path. The problem that I am having is that although the two arrays are mutating and I can see the count of both going up, the following drawRect method only seems to draw the last path in the array.
I have scoured through a lot of questions and based on what I have read so far, this very problem seems to get us newbies and mostly because of type mismatch. I even tried to Typecast the return and it was futile.
Here is my code from the drawRect
int cnt = paths.count;
if (cnt != 0)
{
for(int i = 0; i < cnt; i++)
{
NSLog(#"Drawing path:%i", i);
UIColor *color;
color = [colors objectAtIndex:i];
[color setStroke];
UIBezierPath *path = [paths objectAtIndex:i];
path.lineWidth = 2;
[path stroke];
}
}
every time I call [self setNeedsDisplay] it wipes out my entire screen.
Am I correct in assuming that I am not handling my
UIBezierPath *path = [paths objectAtIndex:i];
well?
Thank you very much and in advance.
UPDATE:
I was rummaging through some more codes and now it almost looks like there is another possibility that ARC is releasing the contents of my NSMutable array. I tried the do the following and got a compiler error.
[paths retain];
Besure you add your path to your path array afer each draw
- (void)drawRect:(CGRect)rect {
[brushPattern setStroke];
UIBezierPath *drawPath = [UIBezierPath bezierPath];
drawPath.lineCapStyle = kCGLineCapRound;
drawPath.miterLimit = 0;
drawPath.lineWidth = thisLineWidth;
for (UIBezierPath *path in pathArray)
[drawPath appendPath:path];
UIBezierPath *path = [self pathForCurrentLine];
if (path)
[drawPath appendPath:path];
[drawPath stroke];
}
- (UIBezierPath*)pathForCurrentLine {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addLineToPoint:endPoint];
return path;
}
I have problems with a simple NSString on Mac OS X:
NSString *letters = #"abcdefghijklmnopqrstuvwxyz0123456789";
myString = [myString stringByAppendingFormat:#"%c", [letters characterAtIndex:3]];
When I try to access this string again, Xcode is returning EXC_BAD_ACCESS
This error just occures, when I'm using the format #"%c"
When I'm using #"%#", sometimes the same error, sometimes this string: control 0x10040a480 and sometimes this:
{(
<CFRunLoopObserver 0x10015ac60 [0x7fff70731ee0]>{locked = No, valid = Yes, activities = 0x21, repeats = Yes, order = 0, callout = _ZL15FlushAllBuffersP19__CFRunLoopObservermPv (0x7fff88a147d4), context = <CFRunLoopObserver context 0x0>}
)}
The errors occur randomly even, if I don't change anything in the code and re-run it.
I try to get a random String by doing:
randomString = #"";
NSString *letters = #"abcdefghijklmnopqrstuvwxyz0123456789";
srand(time(NULL));
for (int i=0; i<5; i++)
{
randomString = [randomString stringByAppendingFormat:#"%c", [letters characterAtIndex:(rand()%[letters length])]];
}
randomString is declared in header.h
I also tried using a NSMutableString but that didn't work too.
Every time I try to access the string (or mutable string) via #"%#" I'm getting EXC_BAD_ACCESS
Any idea?
Hope somebody can help me!
Greets,
Julian
Your problem is that myString gets autoreleased before you access it.
You need to change:
myString = [myString stringByAppendingFormat:#"%c", [letters characterAtIndex:3]];
to:
myString = [[myString stringByAppendingFormat:#"%c", [letters characterAtIndex:3]] retain];
Remember to run [myString release]; when you are done with it.
this works for me:
define letters at top of file:
#define letters #"abcdefghijklmnopqrstuvwxyz0123456789"
then append a random character like this:
NSString *randomString = #"";
for (int i = 0; i < 5; i++)
{
UInt64 index = rand() % [letters length];
NSString *randomCharacter = [letters substringWithRange: NSMakeRange(index, 1)];
randomString = [randomString stringByAppendingString:randomCharacter];
}
NSLog(#"%#", randomString);