I am having trouble with some code. I narrowed it down to this problem: first of all, reverseString and 2 are both NSMutableStrings _input1 and _input2 are NSStrings, i'm trying to add zeros to the smallest string but it's not working correctly, this is what I got. reverseString is #"123" and reverseString2 is #"34567".
//they get initialized back into the original strings
_input1=reversedString;
_input2=reversedString2;
//appends 0 to the shortest value
while ([_input1 length]>[_input2 length]){
_input2=[_input2 stringByAppendingString:#"0"];
_length=[_input1 length];
}
while ([_input1 length]<[_input2 length]){
_input1=[_input1 stringByAppendingString:#"0"];
_length=[_input2 length];
}
//converts the string to an NSArray
for (int i=0; i <([_input1 length]); i++) {
NSString *TempStr = [_input1 substringWithRange:NSMakeRange(i, 1)];
[one addObject:[TempStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
for (int i=0; i <([_input2 length]); i++) {
NSString *TempStr2 = [_input2 substringWithRange:NSMakeRange(i, 1)];
[two addObject:[TempStr2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
Now I noticed that when it goes through this loop, the smallest one, _input1, gets set to #"" instead of adding zeros to the end. This is within a class, by the way.
This is also an error I receive:
objc[2291]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[2291]: receiver 0x100300830, SEL 0x7fff8a689779, isa 0x7fff727b8bd0, cache 0x7fff727b8be0, buckets 0x7fff89b9b09c, mask 0x1, occupied 0x0, wrap bucket 0x7fff89b9b09c
objc[2291]: receiver 0 bytes, buckets 0 bytes
objc[2291]: selector 'length'
(lldb)
Just try with following code
if([_input1 length] > [_input2 length])
{
for (int i = 0 ; i < [_input1 length] - [_input2 length] ; i ++)
_input2 = [_input2 stringByAppendingString:#"0"];
}
else
{
for (int i = 0 ; i < [_input2 length] - [_input1 length] ; i ++)
_input1 = [_input1 stringByAppendingString:#"0"];
}
Try like this:-
NSString *input1=#"123";
NSString * input2=#"34567";
NSMutableArray *one=[NSMutableArray array];
NSMutableArray *two=[NSMutableArray array];
//appends 0 to the shortest value
while ([input1 length]>[input2 length]){
input2=[input2 stringByAppendingString:#"0"];
//length=[input1 length];
}
while ([input1 length]<[input2 length]){
input1=[input1 stringByAppendingString:#"0"];
// length=[input2 length];
}
for (int i=0; i <([input1 length]); i++) {
NSString *TempStr = [input1 substringWithRange:NSMakeRange(i, 1)];
[one addObject:[TempStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%ld",[one count]);
for (int i=0; i <([input2 length]); i++) {
NSString *TempStr2 = [input2 substringWithRange:NSMakeRange(i, 1)];
[two addObject:[TempStr2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%ld",[two count]);
Well your requirements are not very clear, but here's a cleaner version of the code you proposed
NSString *string1 = #"foo";
NSString *string2 = #"foobar";
// Compute the desired length
NSUInteger length = MAX(string1.length, string2.length);
// We will pad using this string
NSString *paddingString = #"0";
// Pad both strings to the same length
string1 = [string1 stringByPaddingToLength:length withString:paddingString startingAtIndex:0];
string2 = [string2 stringByPaddingToLength:length withString:paddingString startingAtIndex:0];
// Build two arrays containing the characters, percent escaped
NSMutableArray *charactersArray1 = [NSMutableArray arrayWithCapacity:string1.length];
NSMutableArray *charactersArray2 = [NSMutableArray arrayWithCapacity:string2.length];
for (NSInteger i = 0; i < string1.length; i++) {
[charactersArray1 addObject:[[string1 substringWithRange:(NSRange){ i, 1 }] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[charactersArray2 addObject:[[string2 substringWithRange:(NSRange){ i, 1 }] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"String 1: %#\nString 2: %#", charactersArray1, charactersArray2);
The result will be
String 1: [ f, o, o, 0, 0, 0 ]
String 2: [ f, o, o, b, a, r ]
I figured out my problem, _input1 and _input2 were bad pointers and i had to fix it, sorry for all the confusion, in the end i got my code to work!
Related
In my Objective-C code I'd like to take a NSString value, iterate through the letters, sum ASCII values of the letters and return that to the user (preferably as the NSString too).
I have already written a loop, but I don't know how to get the ASCII value of an individual character. What am I missing?
- (NSString*) getAsciiSum: (NSString*) input {
NSInteger sum = 0;
for (NSInteger index=0; index<input.length; index++) {
sum = sum + (NSInteger)[input characterAtIndex:index];
}
return [NSString stringWithFormat: #"%#", sum];
}
Note: I've seen similar questions related to obtaining ASCII values, but all of them ended up displaying the value as a string. I still don't know how to get ASCII value as NSInteger.
Here is the answer:
- (NSString *) getAsciiSum: (NSString *) input
{
NSString *input = #"hi";
int sum = 0;
for (NSInteger index = 0; index < input.length; index++)
{
char c = [input characterAtIndex:index];
sum = sum + c;
}
return [NSString stringWithFormat: #"%d", sum]);
}
This is working for me.
Hope this helps!
This should work.
- (NSInteger)getAsciiSum:(NSString *)stringToSum {
int asciiSum = 0;
for (int i = 0; i < stringToSum.length; i++) {
NSString *character = [stringToSum substringWithRange:NSMakeRange(i, 1)];
int asciiValue = [character characterAtIndex:0];
asciiSum = asciiSum + asciiValue;
}
return asciiSum;
}
Thank you to How to convert a NSString to NSInteger with the sum of ASCII values? for the reference.
split the sentence into words with out using "componentsSeparatedByString:"
my word is "This is a well known simple"
I wrote like this separtedWord=[noteTextView.text componentsSeparatedByString: #" "];
but I want with out using componentsSeparatedByString.please help me
I have wrote following logic. Created two properties like this :
#property(nonatomic,strong) NSMutableArray *strings;
#property(nonatomic,strong) NSMutableString *tempString;
Wrote business logic like this :
NSString *sampleString = #"This is a well known simple";
self.tempString = [[NSMutableString alloc] init];
self.strings = [[NSMutableArray alloc] init];
for( int i = 0; i < sampleString.length; i++ )
{
unichar currentChar = [sampleString characterAtIndex:i];
NSString *character = [NSString stringWithCharacters:¤tChar length:1];
if( currentChar != ' ' )
{
[self.tempString appendString:character];
if( i == sampleString.length - 1 )
{
[self addString:self.tempString];
}
}
else
{
[self addString:self.tempString];
[self.tempString setString:#""];
}
}
NSLog(#"Array Of String = %#",self.strings);
- (void)addString:(NSString *)string
{
[self.strings addObject:[NSString stringWithString:string]];
}
2014-07-24 15:23:22.306 ViemoPlayer[1834:70b] Array Of String = (
This,
is,
a,
well,
known,
simple
)
Hope this helps.
Convert the NSString into a char array.
Loop through the array and an if statement inside, and keep appending the charecters inside the charArray into a local NSMutableString using
for(int i =0;i<[myCharArray count];i++){
NSMutableString *teststring;
[teststring appendString:[myCharArray objectAtIndex : i]];
if([myCharArray objectAtIndex] == " "){
NSLog(teststring);
teststring = #""; //emptying the testString when we get a space
}
}
That should do it
i have a uitableview, which gets populated by a pulling data from a website, so there is a new string for every cell. To that, i want to have show a HEX for the user, based on the text in the cell.
I have tryed myself to make it, without luck, but luckly found a javascript script which does what i try to do. This script, i now need to convert to obj-c, i have tryed it myself, but failed. I hope to get some help.
javascript: http://jsfiddle.net/sUK45/
My try in obj-c (here the strings aint based on the data from the web, but just an array):
unichar hash = 0;
NSArray *strings = [NSArray arrayWithObjects:#"MA", #"Ty", #"Ad", #"ER", nil];
for (int i = 0; i < [[strings objectAtIndex:indexPath.row] length]; i++) {
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash < 5) - hash);
}
NSString *colour = #"#";
for (int i = 0; i < 3; i++) {
int value = (hash >> (i * 8)) & 0xFF;
colour = [NSString stringWithFormat:#"%#%d", colour, value];
}
NSLog(#"%#", colour);
But the data i get, aint a useable HEX - NSlog:
#2432550
#3600
#3400
#1200
Probably this is not the only one mistake. Change
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash < 5) - hash);
to
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash << 5) - hash);
UPDATE:
Also change
colour = [NSString stringWithFormat:#"%#%d", colour, value];
to
colour = [NSString stringWithFormat:#"%#%02x", colour, (unsigned int)value];
UPDATE2:
I have fixed one more error and simplified code:
unsigned int hash = 0;
NSArray *strings = [NSArray arrayWithObjects:#"MA", #"Ty", #"Ad", #"ER", nil];
NSString *string = [strings objectAtIndex:indexPath.row];
for (int i = 0; i < string.length; i++) {
hash = [string characterAtIndex:i] + ((hash << 5) - hash);
}
NSString *color = [NSString stringWithFormat:#"#%06x", hash % 0x1000000];
NSLog(#"%#", color);
I want a string of all the characters of the alphabet randomized. Right now, I create a mutable array of the 26 characters, shuffle them with the exchangeObjectAtIndex: method and then add each character to a string that I return.
There has to be a better way to do this. Here is my code:
- (NSString *)shuffledAlphabet {
NSMutableArray * shuffledAlphabet = [NSMutableArray arrayWithArray:#[#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z"]];
for (NSUInteger i = 0; i < [shuffledAlphabet count]; ++i) {
// Select a random element between i and end of array to swap with.
int nElements = [shuffledAlphabet count] - i;
int n = (random() % nElements) + i;
[shuffledAlphabet exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSString *string = [[NSString alloc] init];
for (NSString *letter in shuffledAlphabet) {
string = [NSString stringWithFormat:#"%#%#",string,letter];
}
return string;
}
Here's an efficient Fisher-Yates shuffle, adapted to your use case:
- (NSString *)shuffledAlphabet {
NSString *alphabet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Get the characters into a C array for efficient shuffling
NSUInteger numberOfCharacters = [alphabet length];
unichar *characters = calloc(numberOfCharacters, sizeof(unichar));
[alphabet getCharacters:characters range:NSMakeRange(0, numberOfCharacters)];
// Perform a Fisher-Yates shuffle
for (NSUInteger i = 0; i < numberOfCharacters; ++i) {
NSUInteger j = (arc4random_uniform(numberOfCharacters - i) + i);
unichar c = characters[i];
characters[i] = characters[j];
characters[j] = c;
}
// Turn the result back into a string
NSString *result = [NSString stringWithCharacters:characters length:numberOfCharacters];
free(characters);
return result;
}
This is the more efficient way to perform a correctly shuffled alphabet generation.
- (NSString *)shuffledAlphabet
{
const NSUInteger length = 'Z' - 'A' + 1;
unichar alphabet[length];
alphabet[0] = 'A';
for ( NSUInteger i = 1; i < length; i++ )
{
NSUInteger j = arc4random_uniform((uint32_t)i + 1);
alphabet[i] = alphabet[j];
alphabet[j] = 'A' + i;
}
return [NSString stringWithCharacters:alphabet length:length];
}
It uses the "inside-out" version of the Fischer Yates shuffle and avoids modula bias by generating the pseudorandom numbers with arc4random_uniform. Also, it requires a single allocation as all the permutations are performed in a temporary buffer.
Generating random numbers in Objective-C does this help?
*generate random number
*divide by 26 and take reminder
*index array[reminder]
You could pick random elements from the (remaining) alphabet while you build your string instead of shuffling it first:
NSMutableArray *alphabet = [NSMutableArray arrayWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
NSMutableString *result = [NSMutableString string];
NSUInteger numberOfLetters = alphabet.count;
for (NSUInteger i = 0; i < numberOfLetters; i++) {
int n = arc4random() % alphabet.count;
[result appendString:[alphabet objectAtIndex:n]];
[alphabet removeObjectAtIndex:n];
}
NSLog(#"%#", result);
This makes the code a bit shorter. Note also that using NSMutableString is more efficient than creating a new NSString each time a letter is added.
I received an NSString from the server. Now I want to split it into the substring which I need.
How to split the string?
For example:
substring1:read from the second character to 5th character
substring2:read 10 characters from the 6th character.
You can also split a string by a substring, using NString's componentsSeparatedByString method.
Example from documentation:
NSString *list = #"Norman, Stanley, Fletcher";
NSArray *listItems = [list componentsSeparatedByString:#", "];
NSString has a few methods for this:
[myString substringToIndex:index];
[myString substringFromIndex:index];
[myString substringWithRange:range];
Check the documentation for NSString for more information.
I wrote a little method to split strings in a specified amount of parts.
Note that it only supports single separator characters. But I think it is an efficient way to split a NSString.
//split string into given number of parts
-(NSArray*)splitString:(NSString*)string withDelimiter:(NSString*)delimiter inParts:(int)parts{
NSMutableArray* array = [NSMutableArray array];
NSUInteger len = [string length];
unichar buffer[len+1];
//put separator in buffer
unichar separator[1];
[delimiter getCharacters:separator range:NSMakeRange(0, 1)];
[string getCharacters:buffer range:NSMakeRange(0, len)];
int startPosition = 0;
int length = 0;
for(int i = 0; i < len; i++) {
//if array is parts-1 and the character was found add it to array
if (buffer[i]==separator[0] && array.count < parts-1) {
if (length>0) {
[array addObject:[string substringWithRange:NSMakeRange(startPosition, length)]];
}
startPosition += length+1;
length = 0;
if (array.count >= parts-1) {
break;
}
}else{
length++;
}
}
//add the last part of the string to the array
[array addObject:[string substringFromIndex:startPosition]];
return array;
}