Code to generate random strings creates same succession of identical strings - iphone

I have the following method that should create a 20 character ID (sometimes with a prefix) and return the ID.
It seems to reset on launch and every time I use it it will create the same succession of identical numbers.
+(NSString *)createUniqueIdentifier:(NSString *)withPrefix {
NSString *outstring = nil;
if (withPrefix!=nil && ![withPrefix isEqualToString:#""]) {
outstring = [withPrefix stringByAppendingString:#"-"];
} else {
outstring = #"";
}
NSInteger ii;
NSString *allletters = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (ii=0; ii<20; ii++) {
outstring = [outstring stringByAppendingString:[allletters substringWithRange:[allletters rangeOfComposedCharacterSequenceAtIndex:random()%[allletters length]]]];
}
return outstring;
}
I'm assuming this has something to do with random(), but I don't know what else to use. I think I even got that suggestion from Stack Overflow.
Thanks for any help!

When using random() you should set the seed value at program start, ie srandom(time(NULL));

My guess is that you probably need to set the seed since it'll use a default one if you don't.
You should at least use something based on the date/time to get something that varies for each run.

If you'd like a completely unique string, I'd use NSProcessInfo to generate one for you by calling:
[[NSProcessInfo processInfo] globallyUniqueString];
Unless you only want it to contain those letters mentioned.

I think I've figured it out. I changed random() to arc4random() and it magically seems to work now.
Here's the documentation on arc4random that probably has something to do with it:
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (21700) states. The arc4random() function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore has twice the range of rand(3) and random(3) .
The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom().
There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself.

FYI: If you absolutely need unique strings, create a UUID instead of using random, which has a minute chance of getting identical values.

Related

How to Multiply Two textfield values Without converting the text into integer or Number

I have two text fields and user entered the values. I can get the values of textFields like below
NSString *number1 = firstTextField.text;
NSString *number2 = secondTextField.text;
I want to multiply number1 and number2 without converting them into integer or number.I am doing like below
NSExpression *expression = [NSExpression expressionWithFormat:[NSString stringWithFormat:#"%#*%#",number1,number2]];NSLog(#"Multiplication result is----%#",[expression expressionValueWithObject:nil context:nil]);
I don't know if it is correct or not. If it is not correct please give me the suggestions how it can be possible.
By using NSExpression is one way to Multiply/Add/Subtract two number strings without converting them into integer or number.
NSExpression *expression = [NSExpression expressionWithFormat:expressionFormat];
You are using here expressionFormat as [NSString stringWithFormat:#"%#*%#",number1,number2];.
If you want to add or subtract number1 and number2 then replace * with + or -. In this way you have to proceed.
If the question was in an interview.
The interviewers were probably expecting you to write a method to go through both arrays and multiply the characters (converting one by one to integers) or (also identifying the represented character to know the equivalent integer number).
Searching on google there are some examples in different languages.
JAVA
http://csjobinterview.wordpress.com/2012/04/05/string-multiplication/
string multiplication
C++
Multiplying two number arrays
It is a common question in interviews.
I simply used textfields... and used the values that the user input into those textfields... here is one calculation example that has worked for me... in this example the user is trying to find the volume of beachstone they would need to order... the formula is pretty straight forward. Make sure you use the math brackets () to distinguish order of operations...
-(IBAction)calculate_beachstone:(id)sender {
float floatanswer =
([area1.text floatValue])+([area2.text floatValue])+([area3.text floatValue])+([area4.text floatValue])+([area5.text floatValue])+([area6.text floatValue])+([area7.text floatValue])+([area8.text floatValue])+([area9.text floatValue])+([area10.text floatValue]))
*([beachstone_depth.text floatValue])/12)/27);
NSString *stringRectResult=[[NSString alloc]
initWithFormat:#"%.1f",floatanswer];
answer_beachstone.text=stringRectResult;
}
I am adding the text found in the textfield (which user can only use numbers for input - custom keyboard)... in this example I have up to 10 fields which can be added together... then I use the * (multiply) to apply a depth in this example, and convert it back to a text string so I can display the result somewhere else...
In fact, if you write this part answer_beachstone to NSUserDefaults, you can use the result anywhere in different controllers, by calling it back.
If you're interested, here is how I did that...
-(IBAction)save_answer_beachstone:(id)sender {
save_answer_beachstone = [[NSString alloc] initWithString:answer_beachstone.text];
[answer_beachstone setText:save_answer_beachstone];
NSUserDefaults *save = [NSUserDefaults standardUserDefaults];
[save setObject:save_answer_beachstone forKey:#"save_answer_beachstone"];
}
Then I can use the resulting "answer" in any controller inside viewDidLoad...
[answer_beachstone setText:[[NSUserDefaults standardUserDefaults] objectForKey:#"save_answer_beachstone"]];
I know the question was asked 4 years ago, but this formula syntax works for me in a number of ways, in various apps...
You can't multiply two strings. It's not possible.
For this you have to convert it into Integer or int using NSNumber or using:
[secondTextField.text intValue].
NSInteger number = [firstTextField.text integerValue]*[secondTextField.text integerValue];

Check if textfield text is almost equal to string

I have a UITextField called textfield. And I have this code to check if the text in the textfield is equal to "exampletext"
if ([textfield.text isEqualToString:#"exampletext"]) {
NSLog(#"Correct");
} else {
NSLog(#"Wrong");
}
But I also want to check if the text in the textfield is almost equal to "exampletext", if the text is almost the same as "exampletext". Like if the text was "eampletex" I want to NSLog(#"Close")
Are there any ways to check if the textfield text is like 50% equal to "exampletext"?
Or any ways to check if the textfield text has 50% the same characters as "exampletext"?
Or something else like that?
What you are looking for is an implementation of the levenshtein distance, levenshtein("hello", "hallo") => 1, levenshtein("hello", "ellos") => 2. You can check this library.
Once you have the distance between the two strings, you could get it as a percentage calculating: percentage = 100 * levenshtein(original,other) / length(original)
Here's my go at it. Create a custom character set from the string you want to match. Check each character in the texfield.text against that character set, and if the number of matches is close to the number of letters in the string, do something..
NSString *testString = #"wordToCompare";
NSString *textFromTextfield = textfield.text;
//create a custom character set from the word you want to compare to...
NSCharacterSet *characterSetForString = [NSCharacterSet characterSetWithCharactersInString:testString];
//keep track of how many matches...
int numberOfCharsThatMatchSet = 0;
for (int x = 0; x < [textFromTextField length]; x++) {
unichar charToCheck = [textFromTextField characterAtIndex:x];
if ([characterSetForString characterIsMember:charToCheck] == YES) {
numberOfCharsThatMatchSet++;
}
NSLog(#"%d", numberOfCharsThatMatchSet);
}
// if the number of matches is the same as the length of the word + or - 2...
if ((numberOfCharsThatMatchSet > [testString length] - 2 ) && (numberOfCharsThatMatchSet < [testString length] + 2 )) {
NSLog(#"close match...");
}
Not sure if this is 100% what you're looking for, but maybe it will help anyway...
I'm sure there might be some open source out there somewhere that would do this for you..however, one approach I can think of that will give you a bit of a lead...
Sort out the characters of both your strings into arrays. Determine which string you want to be the master string and grab the string length of it.
Now compare each character. Ex: Word 1: hello, Word 2: ello.
Each time a letter is found add one to a count. If by the end of your looping your count is 80% of the original length you grabbed from the master string or greater then you most likely have a partial match.
So for our example Word 1 will be our master string and its length is 5. "ello" contains 4/5 characters and therefore is matches 80% of the original string.
I don't think there is an easy way (with several lines of code) of solving this. There are several algorithms you might consider and pick the one which suits your needs most.
You should look at this question. Although it has been designed and answered for another language, you asked for a way or method so you have your solution there.

Compare, Getting string from a label

I'm making a word game and I've finally come up to one of the most important parts of my game, the compare part.
I got this label which will be invisible when it launches with the word that has to be guessed displaying in it with a random word generator. For example the word is: GARAGE
Now, for my game I have to compare the word with the input now I've already done this with the entire word with NSString but I want it to compare every letter. I want to be able to show that if the input has G as the first letter aswell, like garage. I want it to do something.
I want to know if this is possible and which methods you would use. I was thinking about making 6 strings since all my random words have 6 letters, and then break the word to 6 strings and the input aswell and then compare strings?
Hope someone has some usefull tips or example code thanks
So, assuming your string to be guessed...
NSString *stringToGuess = #"GARAGE";
and you were checking to see if it started with "GA"
NSString *myString = #"GA";
you would check it with hasPrefix:
if ([stringToGuess hasPrefix:myString]) {
// <stringToGuess> starts with <myString>
}
The documentation for NSString describes lots of neat methods for just about anything string related.
hasPrefix will let you tell if one string begins with another string. There's also characterAtIndex. You could use that to get one character from each string and compare it to the other.
You could write a method that would take an integer index and compare the two strings at that index:
- (BOOL) compareStringOne: (NSString *) stringOne
toStringTwo: (NSString *) stringTwo
atIndex: (NSUInteger) index;
{
if ([stringOne length] < index+1 || [stringTwo length] < index+1)
return FALSE;
return [stringOne characterAtIndex: index] == [stringTwo characterAtIndex: index];
}

Creating and managing two independent random number sequences

I'm having trouble generating two independent random sequences using the rand and srand functions. The details are below, any help would be most appreciated.
I'm working on a puzzle game for the iPhone, and usually for the random number generation I use the arc4 function. However for the multiplayer mode I want both players to have the same pieces throughout the game, and the only way I can control it is to have two repeatable random sequences. If I then send the seeds to the other device, the games will be identical. However when I use rand and srand and try to switch to the other seed, the sequence starts from scratch, I somehow have to initialize two independent sequences generated with a seed.
Thank you for your responses
Cryptographically bad PRNGs like rand() operate by feeding the previous result back into a certain mathematical procedure.
In order to continue a sequence from where it left off, all you have to do is store the last-generated number and use it as the seed:
srand(time(0));
int player1_rand_num = rand();
NSLog(#"Player 1: %d, %d, %d", rand(), rand(), rand());
srand(7);
int player2_rand_num = rand();
NSLog(#"Player 2: %d, %d, %d", rand(), rand(), rand());
// Re-seed Player 1 sequence
srand(player1_rand_num);
// Displays the same "random" numbers as the first NSLog
NSLog(#"Player 1 again: %ld, %ld, %ld", rand(), rand(), rand());
// and so on...
The random() function generates better random numbers, and has a separate pair of functions, initstate() and setstate() which will give you the state of the generator. You can store the state and pass it into setstate() to resume the sequence from where you left off. I direct you to man 3 random for the details.
First off, as others have pointed out already, you should use random() instead of rand(). Secondly, while your singleton approach may work for you, you could solve your problem more easily and IMHO more elgantly by using setstate(3). See Use of setstate(3) doesn't produce expected sequence of random numbers for an example on how to switch between two random number states.
Thank you for the suggestions, this is how I implemented the whole thing. I created a singleton class with 2 instance variables - seed1 and seed2 - anytime I want to get a number from the first generator I use the method generator1, same for generator2 method. The seed1/2 is instantly set to a newly generated number every time so I can just continue where I left off. In conlusion, Josh Caswell gave me all the information I needed. Check out the code if you ever need something like this. The object inits with seeds 1 and 1 but during the game they get replaced with some other numbers that both devices share.
#implementation RandomNumberGenerator
#synthesize seed1,seed2;
static RandomNumberGenerator *sharedGenerator = nil;
+(RandomNumberGenerator *) sharedInstance
{
if(!sharedGenerator) {
sharedGenerator = [[RandomNumberGenerator alloc] initWithSeed1:1 andSeed2:1];
}
return sharedGenerator;
}
-(id) initWithSeed1:(int) seedOne andSeed2:(int) seedTwo{
self = [super init];
if (self)
{
seed1 = seedOne;
seed2 = seedTwo;
}
return self;
}
-(int) generator1{
srand(seed1);
int j = rand();
seed1 = j;
return abs(j);
}
-(int) generator2 {
srand(seed2);
int k = rand();
seed2 = k;
return abs(k);
}
-(int) giveRandom {
//return abs(arc4random());
return abs(arc4random());
}
#end
Did you seed your random number generator?
srand( myIdenticalSeedValueForBothPartners );
See this question or here [C++ reference].
In case you don't need to call rand() many thousand times:
int nthRandBasedOnSeed( int seed, int count ) {
srand( seed );
int result;
while( 0 < count-- ) {
result = rand();
}
return result;
}
Alternately, you might consider sending with the seed a "count". This count would simply indicate where in the seeded-series you are and would get incretented each time you generate a random number with that seed. This approach gives you the flexibility of using any random generator you like and keeps communication to a minimum.
int playerSeed = 12345;
int playerRndCount = 0;
int generateRandomNumber() {
playerRndCount++;
return rand();
}
void synchSeed(seed, count) {
srand(seed);
for (int i=0; i<count; i++)
generateRandumNumber();
}
Some random number generator libraries allow you to save the state of the generator. This way, you can restore it later, and continue with a sequence already in progress. One I know of is called RandomLib, and it can be found on SourceForge.
Another option is save the seed, and count how many times you've pulled a value from the generator after seeding. Later on when you want to continue, reseed with the original seed, and pull off the same quantity. This probably isn't the best method, but should work fine if not done a lot.

What is the fastest routine to convert NSArrays to C-style (double) arrays?

I have 2 NSArray (Mutable, actually) that I am trying to convert to a C-style double array for a c routine i am passing them to.
Here is my Objective-C routine:
NSMutableDictionary *childDictionary = [myParentDictionary objectForKey:resort_code];
latitudeArray = [childDictionary objectForKey:#"lat"];
longitudeArray = [childDictionary objectForKey:#"lon"];
int nvert = [latitudeArray count];
double laArray[nvert];
double loArray[nvert];
for(int i=0; i<nvert; i++) {
double dLat = [[latitudeArray objectAtIndex:i]doubleValue];
double dLon = [[longitudeArray objectAtIndex:i]doubleValue];
laArray[i] = dLat;
loArray[i] = dLon;
}
This takes upwards of 3-8 seconds on the 3G iPhone (instantaneous on the simulator -- yet another reason to test on the device )
is there faster way? I have to end up with laArray[i] and loArray[i] as c-style arrays of doubles.
(to expand on the question for the benefit of a commenter):
Each array consists of #"38.448745" (lat) and #"-122.9847684" (lon) style content. I do this cos to be pushed onto an NSArray, the lat and lon need to be objects. I simply used:
[latitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlat]];
[longitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlon]];
I suppose I could change that to:
[latitudeArray addObject:[NSNumber numberWithDouble: #"%.10f",dlat]];
[longitudeArray addObject:[NSNumber numberWithDouble: #"%.10f",dlon]];
...which may reduce the conversion time of
double dLat = [[latitudeArray objectAtIndex:i]doubleValue];
but wouldn't I still need that exact line to convert from NSString to double? It just may work faster?
thx
dlat is a double, right?
So instead of:
[latitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlat]];
Do:
[latitudeArray addObject:[NSNumber numberWithDouble:dlat]];
They both respond to doubleValue but the NSNumber should not have to do any string parsing since it's stored as a numeric value already. And you never have to go to a string at all.
I suspect you have an array of strings like #"213.12385" that need to be parsed and converted when you call doubleValue on them. If that is where the issue is, the C arrays have nothing to with this.
Only thing I would add here is to throw Shark on this and see where it's spending it's time. If it's spending time in doubleValue find a different way to parse the strings with preprocessing in background or something. If it's in objectAtIndex: perhaps fast enumeration would help. If it's somewhere else entirely then you know it's not this snippet that's slow.
For the general case of converting an NSArray to a C array, you can use getObjects:. In this case, though, want you actually want is not to convert the NSArray, but to derive an array of doubles from an NSArray of some unspecified object type.
One obvious way to speed things up would be fast enumeration rather than sending a message to get the object for each iteration of the loop. I suspect the real solution, though, is outside your algorithm. The slowness probably comes from transforming whatever objects the array contains into doubles, in which case you'll need to find a way around that — maybe store doubles all along, maybe do the conversion in the background, etc. If you're creating the arrays yourself and there isn't some compelling reason for the objects to be strings, you should use NSNumbers instead. Those should be quite a bit faster.
The best solution is probably to make sure those values never end up in an NSArray as NSString values. I would attack this at the source.
So you edited your question and added that you are actually building those arrays. So why not use native arrays of doubles or floats from the start? I usually recommend against this but in your case it sounds like there is a huge performance gain.
Possibly using fast iteration, but I doubt that will really speed up your loop.