Perceptron, Network paralyze - objective-c

I'm trying to implement perceptron on Objective-C. Now i'm facing the problem that after some random amount of epochs, when error's tending to its minimum or maximum, network is paralysis, and after some more epochs all weights becomes very big or very small numbers, and output and propagation of network becomes NaN. What could be the problem?
My code is here, the main method is learn:
Neuron.h
#interface Neuron : NSObject <NSCoding>
#property (nonatomic) double output;
#property (strong,nonatomic) NSMutableArray *weights;
#property (nonatomic) double propagation;
#end
Web.h
#import "Neuron.h"
#interface Web : NSObject
#property (strong,nonatomic) NSMutableArray *arrayOfLayers;
-(void)setupWebWithNumberOfNeutrons:(NSInteger)number inputArray:(NSArray*)input;
-(void)addToLearningData:(NSArray *)array;
-(void)saveLearningArrayWithPath:(NSString *)path;
-(void)learn;
-(void)setupWeb;
#end
Web.m
#interface Web() <NSCoding>
#property (nonatomic) NSInteger numberOfHiddenLayerNeutrons;
#property (nonatomic) double output;
#property (nonatomic) double propagation;
#property (nonatomic) double answer;
#property (strong,nonatomic) NSMutableArray *learningArray;
#property (strong,nonatomic) NSMutableArray *learningData;
#property (strong,nonatomic) NSMutableArray *epocheLearningArrays;
#property (strong,nonatomic) NSMutableArray *epocheTestingArrays;
#end
const NSInteger kNumberOfHiddenNeurons = 20;
const NSInteger kNumberOfEpocheLearningArray = 70;
const NSInteger kMaxEpocheCount = 100;
#implementation Web
#pragma mark - Properties
-(NSMutableArray *)learningArray
{
if (!_learningArray) {
_learningArray = [[NSMutableArray alloc] init];
}
return _learningArray;
}
-(NSMutableArray *)learningData {
if (!_learningData) {
_learningData = [NSMutableArray array];
}
return _learningData;
}
-(NSMutableArray *)epocheLearningArrays {
if (!_epocheLearningArrays) {
_epocheLearningArrays = [NSMutableArray array];
}
return _epocheLearningArrays;
}
-(NSMutableArray *)epocheTestingArrays {
if (!_epocheTestingArrays) {
_epocheTestingArrays = [NSMutableArray array];
}
return _epocheTestingArrays;
}
-(NSMutableArray *)arrayOfLayers
{
if (!_arrayOfLayers) {
_arrayOfLayers = [[NSMutableArray alloc] init];
}
return _arrayOfLayers;
}
-(void)addToLearningData:(NSArray *)array
{
[self.learningData addObject:array];
[self saveLearningDataWithPath:nil];
}
#pragma mark - Setup
-(void)setupWeb {
NSMutableArray *arrayOfInputNeurons = [[NSMutableArray alloc] init];
for (int i=0; i < 100; i++) {
Neuron *neuron = [[Neuron alloc] init];
[arrayOfInputNeurons addObject:neuron];
}
[self.arrayOfLayers addObject:arrayOfInputNeurons];
NSMutableArray *arrayOfFirstHiddenLayerNeurons = [[NSMutableArray alloc] init];
for (int i=0; i < kNumberOfHiddenNeurons; i++) {
Neuron *neuron = [[Neuron alloc] init];
[arrayOfFirstHiddenLayerNeurons addObject:neuron];
}
[self.arrayOfLayers addObject:arrayOfFirstHiddenLayerNeurons];
NSMutableArray *arrayOfSeconHiddenLayerNeurons = [[NSMutableArray alloc] init];
Neuron *outputNeuron = [[Neuron alloc] init];
[arrayOfSeconHiddenLayerNeurons addObject:outputNeuron];
[self.arrayOfLayers addObject:arrayOfSeconHiddenLayerNeurons];
[self setRandomWeights];
}
-(void)setupWebWithNumberOfNeutrons:(NSInteger)number inputArray:(NSArray*)input
{
self.output = 1;
NSMutableArray *arrayOfInputNeurons = [[NSMutableArray alloc] init];
for (NSNumber *state in input) {
Neuron *neuron = [[Neuron alloc] init];
neuron.output = state.intValue;
[arrayOfInputNeurons addObject:neuron];
}
[self.arrayOfLayers addObject:arrayOfInputNeurons];
NSMutableArray *arrayOfFirstHiddenLayerNeurons = [[NSMutableArray alloc] init];
for (int i=0; i < number; i++) {
Neuron *neuron = [[Neuron alloc] init];
[arrayOfFirstHiddenLayerNeurons addObject:neuron];
}
[self.arrayOfLayers addObject:arrayOfFirstHiddenLayerNeurons];
NSMutableArray *arrayOfSeconHiddenLayerNeurons = [[NSMutableArray alloc] init];
Neuron *outputNeuron = [[Neuron alloc] init];
[arrayOfSeconHiddenLayerNeurons addObject:outputNeuron];
[self.arrayOfLayers addObject:arrayOfSeconHiddenLayerNeurons];
if (!self.propagation) {
[self setRandomWeights];
}
[self forwardPass];
Neuron *neuron = (Neuron *)self.arrayOfLayers[2][0];
self.answer = -1;
[self calculatePropagation:neuron];
[self backPass];
[self resetWeights];
}
-(void)setRandomWeights
{
for (NSInteger i=0; i<[self.arrayOfLayers count]-1; i++) {
for (Neuron *neuron in self.arrayOfLayers[i]) {
NSMutableArray *weights = [NSMutableArray array];
for (NSInteger j=0; j<[self.arrayOfLayers[i+1] count]; j++) {
[weights addObject:#((((float) rand() / RAND_MAX) * 1) -0.5)];
}
neuron.weights = weights;
}
}
}
-(void)setInputLayer {
for (int i=0; i<100; i++) {
Neuron *neuron = self.arrayOfLayers[0][i];
NSNumber *output = self.learningArray[i];
neuron.output = output.doubleValue;
}
}
#pragma mark - Algorythm
-(void)learn {
double currentAnswer;
NSMutableArray *shuffledData = [self.learningData mutableCopy];
[self shuffleArray:shuffledData];
[self setRandomWeights];
int countOfLearningArray = (int) (0.7*[self.learningData count]);
for (int k=0; k<countOfLearningArray; k++) {
[self.epocheLearningArrays addObject:[shuffledData objectAtIndex:k]];
}
for (int k=countOfLearningArray; k<[shuffledData count]; k++) {
[self.epocheTestingArrays addObject:[shuffledData objectAtIndex:k]];
}
NSNumber *learningPropagation=#(-100);
NSNumber *testPropagation=#(100);
NSInteger epocheCount=0;
while (fabs(learningPropagation.doubleValue-testPropagation.doubleValue)>0.001 && epocheCount<kMaxEpocheCount) {
learningPropagation = #0;
for (NSArray *learningArray in self.epocheLearningArrays) {
self.learningArray = [learningArray mutableCopy];
NSNumber *lastObject = [learningArray lastObject];
currentAnswer = lastObject.doubleValue;
[self.learningArray removeLastObject];
self.answer = currentAnswer;
[self setInputLayer];
[self forwardPass];
[self calculatePropagation:self.arrayOfLayers[2][0]];
if (fabs(self.output-self.answer)>0.0001) {
[self backPass];
[self resetWeights];
}
learningPropagation = #(learningPropagation.doubleValue + self.propagation);
}
learningPropagation = #(learningPropagation.doubleValue/[self.epocheLearningArrays count]);
testPropagation = #0;
for (NSArray *testArray in self.epocheTestingArrays) {
self.learningArray = [testArray mutableCopy];
NSNumber *lastObject = [testArray lastObject];
currentAnswer = lastObject.doubleValue;
[self.learningArray removeLastObject];
self.answer = currentAnswer;
[self setInputLayer];
[self forwardPass];
[self calculatePropagation:self.arrayOfLayers[2][0]];
testPropagation = #(testPropagation.doubleValue + self.propagation);
}
testPropagation = #(testPropagation.doubleValue/[self.epocheTestingArrays count]);
epocheCount++;
}
}
-(void)calculatePropagation:(Neuron *)neuron
{
self.propagation= 0.5*pow((neuron.output - self.answer), 2);
}
#define alpha 0.5
-(void)forwardPass
{
for (int i=0; i<[self.arrayOfLayers count]-1; i++) {
for (int j=0; j<[self.arrayOfLayers[i+1] count]; j++) {
double sum=0;
for (int z=0; z<[self.arrayOfLayers[i] count]; z++) {
Neuron *neuron = (Neuron *)self.arrayOfLayers[i][z];
sum+=[(NSNumber *)neuron.weights[j] doubleValue]*neuron.output;
}
Neuron *neuron = (Neuron *)self.arrayOfLayers[i+1][j];
neuron.output = tanh(alpha*sum);
}
}
Neuron *outputNeuron = self.arrayOfLayers[2][0];
self.output = outputNeuron.output;
}
-(void)backPass
{
for (NSInteger i=[self.arrayOfLayers count]-1; i>=0; i--) {
for (int j=0; j<[self.arrayOfLayers[i] count]; j++) {
double temp=0;
if (i==[self.arrayOfLayers count]-1) {
Neuron *neuron = (Neuron *)self.arrayOfLayers[i][j];
temp = neuron.output-self.answer;
neuron.propagation = temp;
} else {
for (int z=0; z<[self.arrayOfLayers[i+1] count]; z++) {
Neuron *neuron1 = (Neuron *)self.arrayOfLayers[i+1][z];
Neuron *neuron2 = (Neuron *)self.arrayOfLayers[i][j];
temp = neuron1.propagation * [(NSNumber *)neuron2.weights[z] doubleValue];
}
Neuron *neuron = (Neuron *)self.arrayOfLayers[i][j];
neuron.propagation = temp;
}
}
}
}
#define gamma 0.01
-(void)resetWeights
{
for (int i=0; i<[self.arrayOfLayers count]-1; i++) {
for (int j=0; j<[self.arrayOfLayers[i] count]; j++) {
Neuron *neuron = (Neuron *)self.arrayOfLayers[i][j];
for (int z=0; z<[self.arrayOfLayers[i+1] count]; z++) {
neuron.weights[z] = #([(NSNumber *)neuron.weights[z] doubleValue]- gamma * neuron.propagation * neuron.output);
}
}
}
}
-(void)shuffleArray:(NSMutableArray *)array {
NSUInteger count = [array count];
for (NSUInteger i = 0; i < count; ++i) {
NSInteger remainingCount = count - i;
NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount);
[array exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
}
}

The error was in method resetWeights. The solution:
-(void)resetWeights
{
for (int i=0; i<[self.arrayOfLayers count]-1; i++) {
for (int j=0; j<[self.arrayOfLayers[i] count]; j++) {
Neuron *neuron = (Neuron *)self.arrayOfLayers[i][j];
for (int z=0; z<[self.arrayOfLayers[i+1] count]; z++) {
Neuron *nextLayerNeuron = (Neuron *)self.arrayOfLayers[i+1][z];
neuron.weights[z] = #([(NSNumber *)neuron.weights[z] doubleValue]- gamma * nextLayerNeuron.propagation * neuron.output);
}
}
}
}

Related

combine multiple array values into one string value?

I want to combine the array values into one string.
my arrays are like...
array1=[#"fizan",#"nike",#"pogo"];
array2=[#"round",#"rectangle",#"square"];
array3=[#"frame",#"frame",#"frame"];
I need like this...
value1 = fizan round frame
value2 = nike rectangle frame
value3 = pogo square frame
try this:
NSArray *array1= #[#"fizan",#"nike",#"pogo"];
NSArray *array2= #[#"round",#"rectangle",#"square"];
NSArray *array3= #[#"frame",#"frame",#"frame"];
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:#[array1,array2,array3]];
NSMutableArray *output = [[NSMutableArray alloc] init];
NSString *a;
NSInteger count = array.count;
for (int i = 0; i<array1.count; i++) {
a = #"";
for (int j = 0; j<count; j++) {
a = [a isEqualToString: #""] ? [NSString stringWithFormat:#"%#",[[array objectAtIndex:j] objectAtIndex:i]] : [NSString stringWithFormat:#"%# %#",a,[[array objectAtIndex:j] objectAtIndex:i]];
}
[output addObject:a];
}
for (int i = 0; i < output.count; i++) {
NSLog(#"value %i -> %#",i+1,output[i]);
}
Hope this helps!
UPDATE:
NSArray *array1= #[#"fizan",#"",#"pogo"];
NSArray *array2= #[#"round",#"rectangle",#"square"];
NSArray *array3= #[#"frame",#"frame",#"frame"];
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:#[array1,array2,array3]];
NSMutableArray *output = [[NSMutableArray alloc] init];
NSString *a;
NSInteger count = array.count;
for (int i = 0; i<array1.count; i++) {
a = #"";
for (int j = 0; j<count; j++) {
a = [a isEqualToString: #""] ? [NSString stringWithFormat:#"%#",[[array objectAtIndex:j] objectAtIndex:i]] : [NSString stringWithFormat:#"%# %#",a,[[array objectAtIndex:j] objectAtIndex:i]];
}
[output addObject:a];
}
for (int i = 0; i < output.count; i++) {
NSLog(#"value %i -> %#",i+1,output[i]);
}
I have tested this code. It works perfect. Check again and reconsider the issue.
Do this
NSArray *array1 = #[#"fizan", #"nike", #"pogo"];
NSString *value = [array1 componentsJoinedByString:#" "];
NSLog(#"value = %#", value);
Output will get like
value = fizan nike pogo
For your case
NSArray *completeArray = #[#[#"fizan",#"nike",#"pogo"], #[#"round",#"rectangle",#"square"], #[#"frame",#"frame",#"frame"]];
NSMutableArray *resultArray = [NSMutableArray array];
unsigned long count = 1;
for (int i = 0; i< count; i++) {
NSMutableArray *listArray = [NSMutableArray array];
for (NSArray *itemArray in completeArray) {
count = MAX(count,itemArray.count);
if (i < itemArray.count) {
[listArray addObject:itemArray[i]];
}
}
[resultArray addObject:listArray];
}
for (NSArray *itemArray in resultArray) {
NSString *value = [itemArray componentsJoinedByString:#" "];
NSLog(#"value = %#", value);
}
output
value = fizan round frame
value = nike rectangle frame
value = pogo square frame

Algorithm to find all possible solutions from an array of array

What is the best algorithm to find all possible words from an array of array of character.
Here an example :
From this array : [[A],[B,C,D],[E,F],[G,H]]
I need in return an array of the 12 ordered possibilities [[A,B,E,G],[A,C,E,G], ... , [A,D,F,H]]
Do you know how to implement this algorithm ? If you know it and you provide an example in any language (C,JAVA,Javascript, ...), feel free to share because it's been a day I try to find it ...
Here how I tries to implement it ("array" is an array of array of char):
+ (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++) {
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}
It would be easiest to do this using a recursive method.
Java code
import java.util.Arrays;
public class CartesianProductCalculator {
private char[][] result;
private char[][] sets;
private char[] currentSet;
private int index;
public char[][] calculateProduct(char[][] sets) {
index = 0;
// calculate size of result
int resultSize = 1;
this.sets = sets;
for (char[] set : sets) {
resultSize *= set.length;
}
result = new char[resultSize][];
currentSet = new char[sets.length];
calculateProduct(sets.length-1);
return result;
}
// fills result from right to left
public void calculateProduct(int setIndex) {
if (setIndex >= 0) {
for (char c : sets[setIndex]) {
currentSet[setIndex] = c;
calculateProduct(setIndex-1);
}
} else {
result[index++] = Arrays.copyOf(currentSet, currentSet.length);
}
}
public static void main(String[] args) {
char[][] input = {{'A'},{'B','C','D'},{'E','F'},{'G','H'}};
CartesianProductCalculator productCalculator = new CartesianProductCalculator();
System.out.println(Arrays.deepToString(productCalculator.calculateProduct(input)));
}
}
Objectiv-C
+ (NSArray *) cartesianProductOfArrays(NSArray *arrays) {
int arraysCount = arrays.count;
unsigned long resultSize = 1;
for (NSArray *array in arrays)
resultSize *= array.count;
NSMutableArray *product = [NSMutableArray arrayWithCapacity:resultSize];
for (unsigned long i = 0; i < resultSize; ++i) {
NSMutableArray *cross = [NSMutableArray arrayWithCapacity:arraysCount];
[product addObject:cross];
unsigned long n = i;
for (NSArray *array in arrays) {
[cross addObject:[array objectAtIndex:n % array.count]];
n /= array.count;
}
}
return product;
}
C
#include <stdio.h>
#include <string.h>
void print(int size, char *array[size], int indexs[size]){
char result[size+1];
int i;
for(i = 0; i < size; ++i)
result[i] = array[i][indexs[i]];
result[size] = 0;
puts(result);
}
int countUp(int size, int indexs[size], int lens[size]){
int i = size -1;
while(i >= 0){
indexs[i] += 1;// count up
if(indexs[i] == lens[i])
indexs[i--] = 0;
else
break;
}
return i >= 0;
}
void find_all(int size, char *array[size]){
int lens[size];
int indexs[size];
int i;
for(i = 0; i < size; ++i){//initialize
lens[i] = strlen(array[i]);
indexs[i] = 0;
}
do{
print(size, array, indexs);
}while(countUp(size, indexs, lens));
}
int main(void){
char *array[] = { "A", "BCD", "EF", "GH" };
int size = sizeof(array)/sizeof(*array);
find_all(size, array);
return 0;
}
If you can remove duplicate entries in inner array objects before executing method then you won't get duplicate words in result array.
- (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++)
{
NSArray *cleanedArray = [[NSSet setWithArray:[array objectAtIndex:i]] allObjects];
[array replaceObjectAtIndex:i withObject:cleanedArray];
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}

"NSRangeException" Error, Not Sure Why

I'm making an Objective C program to generate two random arrays and check them for similar numbers. I get the "NSRangeException" on the marked line of code, but I'm not sure why. Here's my code:
// Array Comparator (Check Two Arrays for Similar Numbers)
#interface ArrayComparator: NSObject
{
NSMutableArray *arrayOne;
NSMutableArray *arrayTwo;
}
- (void) generateFirstArray;
- (void) generateSecondArray;
- (void) check;
#end
#implementation ArrayComparator
- (void) generateFirstArray
{
arrayOne = [[NSMutableArray alloc] initWithCapacity: 50];
for (NSUInteger n = 0; n < 50; n++)
{
[arrayOne addObject: #(arc4random_uniform(999) + 1)];
}
for (NSUInteger n = 0; n < 50; n++)
{
printf("%li, ", (long) [arrayOne[n] integerValue]);
}
printf("first array.\n\n");
}
- (void) generateSecondArray
{
arrayTwo = [[NSMutableArray alloc] initWithCapacity: 50];
for (NSUInteger n = 0; n < 50; n++)
{
[arrayTwo addObject: #(arc4random_uniform(999) + 1)];
}
for (NSUInteger n = 0; n < 50; n++)
{
printf("%li, ", (long) [arrayTwo[n] integerValue]);
}
printf("second array.\n\n");
}
- (void) check
{
long similar = 0;
for (NSUInteger n = 0; n < 50; n++)
{
for (NSUInteger m = 0; m < 50; n++)
{
if ([arrayOne[n] integerValue] == [arrayTwo[m] integerValue]) // This is where I get the error.
{
similar++;
}
}
}
printf("There are %li similar numbers between the two arrays!", similar);
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool
{
ArrayComparator *arrayComp = [[ArrayComparator alloc] init];
[arrayComp generateFirstArray];
[arrayComp generateSecondArray];
[arrayComp check];
} return 0;
}
Any help is appreciated, thanks. (Please excuse my noobishness.)
(NSUInteger m = 0; m < 50; n++)
You mean m++.

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

Split NSString with multiple delimiters?

For text bozo__foo!!bar.baz, how to split an NSString containing this into (bozo, foo, bar, baz)?
That is, separe it in components with strings (delimiters) __, !! and ..
You can split the strings using NSCharacterSet. Try this
NSString *test=#"bozo__foo!!bar.baz";
NSString *sep = #"_!.";
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:sep];
NSArray *temp=[test componentsSeparatedByCharactersInSet:set];
NSLog(#"temp=%#",temp);
I'm aware that this question has already been answered but this is a way to separate strings using multiple strings. This is a category to NSString.
- (NSArray<NSString *> *)componentsSeparatedByStrings:(NSArray<NSString *> *)separators
{
NSMutableArray<NSString *> *components = [[NSMutableArray alloc] init];
unichar buffer[self.length + 1];
NSInteger currentOrigin = 0;
NSInteger currentLength = 0;
[self getCharacters:buffer];
for(NSInteger i = 0; i < self.length; i++)
{
unichar currentChar = buffer[i];
currentLength++;
for(NSInteger n = 0; n < separators.count; n++)
{
NSString *currentDivider = [separators objectAtIndex:n];
if(currentDivider.length == 0)
{
return #[self];
}
else if(currentDivider.length > 1)
{
BOOL goodMatch = NO;
for(NSInteger x = 0; x < currentDivider.length; x++)
{
unichar charInDivider = [currentDivider characterAtIndex:x];
if(charInDivider == currentChar)
{
goodMatch = YES;
}
else
{
goodMatch = NO;
break;
}
if(goodMatch == YES && ((x + 1) != currentDivider.length))
{
i++;
currentLength++;
currentChar = buffer[i];
}
}
if(goodMatch == YES)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, (currentLength - currentDivider.length));
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = (i + 1);
currentLength = 0;
[components addObject:newComponent];
NSLog(#"%#", components);
}
}
else // If current divider is only one character long.
{
if([currentDivider characterAtIndex:0] == currentChar)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, (currentLength - 1));
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = (i + 1);
currentLength = 0;
[components addObject:newComponent];
break;
}
}
}
// Handle the end of the string.
if((i + 1) == self.length)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, currentLength);
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = 0;
currentLength = 0;
[components addObject:newComponent];
}
}
return components;
}
Example: "ABCD__EFGHI__JKLMNOP-QRST.UV_WXYZ"
NSLog(#"%#", [test componentsSeparatedByStrings:#[#"__", #"-", #"."]]);
Log Result: "(ABCD, EFGHI, JKLMNOP, QRST, "UV_WXYZ")"
NSString *text = #"bozo__foo!!bar.baz";
NSArray *split1 = [text componentsSeparatedByString:#"__"];
NSArray *split2 = [[split1 lastObject] componentsSeparatedByString:#"!!"];
NSArray *split3 = [[split2 lastObject] componentsSeparatedByString:#"."];
NSLog(#"%#, %#, %#, %#", split1[0], split2[0], split3[0], split3[1]);
More functional solution is to apply -componentsSeparatedByString: recursively, for each component, which was derived during previous separator application:
NSString Category
- (NSMutableArray<NSString *> *)gvr_componentsSeparatedByStrings:(NSArray<NSString *> *)separators {
if (separators.count == 0) {
return [NSMutableArray arrayWithObject:self];
}
NSString *separator = [separators firstObject];
NSArray *reducedSeparators = [separators gvr_arrayByRemovingFirstObject];
NSArray *components = [self componentsSeparatedByString:separator];
NSMutableArray *result = [NSMutableArray new];
for (NSString *component in components) {
NSMutableArray *subResult = [component gvr_componentsSeparatedByStrings:reducedSeparators];
[result addObjectsFromArray:subResult];
}
return result;
}
NSArray Category
- (NSArray *)gvr_arrayByRemovingFirstObject {
NSMutableArray *result = [NSMutableArray new];
for (NSInteger i = 1; i < self.count; i++) {
[result addObject:self[i]];
}
return [result copy];
}
I solved it for my project by looking for the longest separator, replacing the others with this one, then do the separation on the only one left.
Try this:
NSString *test = #"bozo__foo!!bar.baz";
test = [test stringByReplacingOccurrencesOfString:#"!!" withString:#"__"];
test = [test stringByReplacingOccurrencesOfString:#"." withString:#"__"];
NSArray<NSString *> *parts = [test componentsSeparatedByString:#"__"];