Count number of arbitrary repeating decimal numbers in NSString - objective-c

In my code, I'm dealing with an NSString that contains an NSNumber value. This NSNumber value could possibly be a repeating decimal number (e.x. 2.333333333e+06) that shortens to "2.333333" in a string format. It could also be a terminating number (e.x. 2.5), negative, or irrational number (2.398571892858...) (only dealing with decimals here)
I need to have a way to figure out if there are the repeating numbers in the string (or the NSNumber, if necessary). In my code, I would have no way to know what the repeating number would be, as it's a result of computations started by the user. I have tried this for loop (see below) that doesn't work the way I want it to, due to my inexperience with string indexing/ranges/lengths.
BOOL repeat = NO; //bool to check if repeating #
double repNum, tempNum; //run in for loop
NSString *repeating = [numVal stringValue]; //string that holds possible repeating #
for (int i = 3; i <= [repeating length]-3; i++) { //not sure about index/length here
if (i == 3) {
repNum = [repeating characterAtIndex:i];
}
tempNum = [repeating characterAtIndex:i];
if (tempNum == repNum) {
repeat = YES;
} else {
repeat = NO;
}
}
This code doesn't work as I'd like it to, mainly because I also have to account for negative dashes in the string and different amounts of numbers (13 1/3 vs. 1 1/3). I've used the modffunction to separate the integers from the decimals, but that hasn't worked well for me either.
Thank you in advance. Please let me know if I can clarify anything.
EDIT:
This code works with the finding of different solutions for polynomials (quadratic formula). Hope this helps put it into context. See here. (Example input)
NSNumber *firstPlusSolution, *secondMinusSolution;
NSString *pValueStr, *mValueStr;
firstPlusSolution = -(b) + sqrt(square(b) - (4)*(a)*(c)); //a, b, c: "user" provided
firstPlusSolution /= 2*(a);
secondMinusSolution = -(b) - sqrt(square(b) - 4*(a)*(c));
secondMinusSolution /= 2*(a);
pValueStr = [firstPlusSolution stringValue];
mValueStr = [secondMinusSolution stringValue];
if ([NSString doesString:pValueStr containCharacter:'.']) { //category method I implemented
double fractionPart, integerPart;
fractionPart = modf(firstPlusSolution, &integerPart);
NSString *repeating = [NSString stringWithFormat:#"%g", fractionPart];
int repNum, tempNum;
BOOL repeat = NO;
//do for loop and check for negatives, integers, etc.
}
if ([NSString doesString:mValueStr containCharacter'.']) {
//do above code
//do for loop and check again
}

Use C. Take the fractional part. Convert to a string with a known accuracy. If length of string indicates that last digits are missing, then it does not repeat. Use NSString-UTF8String to convert a string. Get rid of the last digit (may be rounding or actual floating point arithmetic error). Use function int strncmp ( const char * str1, const char * str2, size_t num ) to perform comparison within the string itself. If the result is 8 characters long and the last 2 characters match the first 2 characters, then shall the first 6 characters be considered repeating?
Assuming that fraction knowledge your desire:
• Possibility 1: Use fractions. Input fractions. Compute with fractions. Output fractions. Expand upon one of the many examples of a c++ fraction class if necessary and use it.
• Possibility 2: Choose an accuracy which is much less than double. Make a fraction from the result. Reduce the fraction allowing rounding based upon accuracy.

I suggest use not optimal but easy to write solution
Create NSMutableDictionary that will contain number as key and count of occurrence as value.
You can use componentsSeparatedByString: if numbers in string delimited by known symbol
In loop check valueForKey in dictionary and if need increase value
Last step is analyzing our dictionary and do anything you need with numbers

Related

Reverse a double value

I'm trying to reverse a double value like this:
Input: 1020304050...... Output: 5040302010
the group of 2 digits remain in the same order. So 10 doesn't become 01. or 53 doesn't become 35.
The input will always have even number of digits, so pairing isn't an issue.
The 2 adjacent digits are actually a code number for a function. And I want to maintain that so I can apply that function again.
double temp = 0.0;
double Singlefilter=1;
double reverseString=0;
temp=filtersequence;
while (temp>0)
{
Singlefilter=fmod(temp, 100.00);
temp=temp/100;
reverseString=(reverseString+Singlefilter)*100;
NSLog(#"reversed string of filter %f",reverseString);
}
But I have no idea why this isn't working. This is generating randomly very very big values.
[This question has been replaced by Reverse a double value while maintaining 2 adjacent digits in same format]
You can do it like this:
#import <Foundation/Foundation.h>
#include "math.h"
void outputGroupReversed(double filtersequence)
{
double reverseString = 0.0;
double temp = filtersequence;
while (temp > 0.0)
{
double groupMultiplier = 100.0;
double singleFilter = fmod(temp, groupMultiplier);
temp = floor(temp / groupMultiplier);
reverseString = reverseString * groupMultiplier + singleFilter;
}
NSLog(#"reversed string of filter %f", reverseString);
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
outputGroupReversed(1020304050.0);
}
return 0;
}
This code does not handle input with a fractional part correctly, though.
You're better off just converting it to a string and reversing it.
NSString *inputString = [#(input) stringValue]; // Eg 1230
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [inputString length];
while (charIndex > 0) {
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedString appendString:[inputString substringWithRange:subStrRange]];
}
double result = [reversedString doubleValue]; // Eg 0321 -> 321
// Go back to NSString to get the missing length
NSString *resultString = [#(result) stringValue]; // Eg. 321
// Multiple by factors of 10 to add zeros
result *= exp(10, [inputString length] - [resultString length]); // 3210
NSLog(#"reversed value %f", result);
Reverse string method from this answer.
If you wish to store 2-digit decimal integers packed together as a single numeric value you would be better of using uint64_t - unsigned long 64 bit integers rather than double. That will store 9 pairs of two decimal digits precisely which appears to be one more than you need (you mention 16 digits in a comment).
As long as the numeric value of the packed pairs is not important, just that you can pack 8 2-digit decimal numbers (i.e. 0 -> 99) into a single numeric value, then you can do better. A 64-bit integer is 8 pairs of 2-hexadecimal digit numbers, or 8 8-bit bytes, so you can store 8 values 0 -> 99 one per byte. Now adding and extracting values becomes bit-shifts (>> & << operators) by 8 and bitwise-or (|) and bitwise-and (&). This at least makes it clear you are packing values in, which divide & remainder do not.
But there is another payoff, your "reverse" operation now becomes a single call to CFSwapInt64() which reverses the order of the bytes.
However having said the above, you really should look at your model and consider another data type for what you are doing - long gone are the days when programs had to pack multiple values into words to save space.
For example, why not just use a (C) array of 8-bit (uint8_t values[8]) integers? If you require you can place that in a struct and pass it around as a single value.

Concatenating an int to a string in Objective-c

How do I concatenate the int length to the string I'm trying to slap into that array so it is "C10" given length == 10, of course. I see #"%d", intVarName way of doing it used else where. In Java I would of done "C" + length;. I am using the replaceObjectAtIndex method to replace the empty string, "", that I have previously populated the MSMutableArray "board" with. I am getting an error though when I add the #"C%d", length part at the end of that method (second to last line, above i++).
As part of my homework I have to randomly place "Chutes" (represented by a string of format, "C'length_of_chute'", in this first assignment they will always be of length 10 so it will simply be "C10") onto a game board represented by an array.
-(void)makeChutes: (int) length {// ??Change input to Negative number, Nvm.
//??Make argument number of Chutes ??randomly?? across the board.
for(int i = 0; i < length;){
int random = arc4random_uniform(101);
if ([[board objectAtIndex:random] isEqual:#""]) {
//[board insertObject:#"C%d",length atIndex:random];
[board replaceObjectAtIndex:random withObject:#"C%d",length];
i++;
}
}
}
Please ignore the extra and junk code in there, I left it in for context.
In Objective-C the stringWithFormat method is used for formatting strings:
NSString *formattedString = [NSString stringWithFormat:#"C%d", length];
[someArray insertObject:formattedString];
It's often easier to create your formatted string on a line of its own in Objective-C, since as you can see the call can be fairly verbose!

NSString intValue not working for retrieving phone number

I have a phone number formatted as an easy to read phone number, i.e., (123) 123-4567
However, when I want to use that phone number in code, I need to parse that string into a number variable (such as an int)
However, [string intValue]; doesn't work - I've used intValue about a million times in previous projects, all with no problem, however here, every string I pass in, I get the same, random int back out:
- (int)processPhoneNumber:(NSString *)phoneNumber {
NSMutableString *strippedString = [NSMutableString stringWithCapacity:10];
for (int i=0; i<[phoneNumber length]; i++) {
if (isdigit([phoneNumber characterAtIndex:i])) {
[strippedString appendFormat:#"%c",[phoneNumber characterAtIndex:i]];
}
}
NSLog(#"clean string-- %#", strippedString);
int phoneNumberInt = [strippedString intValue];
NSLog(#"**** %d\n &i", phoneNumberInt, phoneNumberInt);
return phoneNumberInt;
}
Then when I call this method:
NSLog(#"%i", [self processPhoneNumber:self.phoneNumberTextField.text]);
I get: 2147483647. Every input I give this method returns: 2147483647
As CRD has already explained, you're trying to convert that string to a type that's too small to hold the value, and you're getting back the maximum possible value for that type.
Your real problem is deeper, however. A phone "number" isn't really a number. It doesn't represent a quantity. You would never perform arithmetic on one. It's actually a string of digits, and you should handle it that way. Don't convert it; just operate on the string.
See also What's the right way to represent phone numbers?
2147483647 is INT_MAX which is returned on overflow. How large is your phone number, will it fit into an int? Maybe you should use longLongValue?

How to extract elements of NSArray and convert them(parseInt) to integer values?

I have a string which is a 13 digit number. I need to separate all the digits and find the sum of the individual digits. How can I do that?
I converted the string to NSArray like this :
NSArray *arrStrDigits = [str13DigitNumber componentsSeparatedByString:#""];
now I want to run a loop and get something like arrStrDigits[i]
I am new to Objective C :(. Please help me out!
Get the individual digits like this:
unichar digitChar = [str13DigitNumber characterAtIndex: someIndex];
// Should put in some validation that you have a digit here
int digit = digitChar - '0';
That just needs to go in a loop where you iterate someIndex from 0 to [str13DigitNumber length]
int total=0;
for(NSString *numberInString in arrStrDigits)
{
total+=[numberInString intValue];
}
Note: I am assuming you have int's in each position of your array.
Note 1: This answer is only related to what you ask (run a loop, nothing else).

Converting NSString to a decimal

I need to change the code below to make "intAmount" a decimal or an integer (i.e. a person can enter .10 or 1) in my uitextfield. The last line "myProduct" has to be a decimal not an integer and return the product in the format "18.00" for example. Can someone help someone help me alter my code snippit for this?
//amt has to be converted into a decimal value its a NSString now
NSInteger intAmount = [amt intValue];
//where total gets updated in the code with some whole (integer) value
NSInteger total=0;
//Change myProduct to a decimal with presicion of 2 (i.e. 12.65)
NSInteger myProduct=total*intAmount;
THIS DOESN'T WORK
NSDecimalNumber intAmount = [amt doubleValue];
//Keep in mind totalCost is an NSInteger
NSDecimalNumber total=totalCost*intAmount;
Use doubleValue instead of intValue to get the correct fractional number out of your text field. Put it in a variable of type double rather than NSInteger. Then use the format %.2g when you print it out and it will look like you want it to.
If you need to track decimal values explicitly, you can use NSDecimalNumber. However, if all you're doing is this one operation, Carl's solution is most likely adequate.
If you have a string representation of a real number (non-integer), you can use an NSScanner object to scan it into a double or float, or even an NSDecimal structure if that is your true intention (the NSDecimal struct and NSDecimalNumber class are useful for containing numbers that can be exactly represented in decimal).
NSString *amt = #"1.04";
NSScanner *aScanner = [NSScanner localizedScannerWithString:amt];
double theValue;
if ([aScanner scanDouble:&theValue])
{
// theValue should equal 1.04 (or thereabouts)
}
else
{
// the string could not be successfully interpreted
}
The benefit to using a localised NSScanner object is that the number is interpreted based on the user's locale, because “1.000” could mean either one-thousand or just one, depending on your locale.