我已经在Python中为我的iOS游戏制作了一个算法原型,我需要在ObjC中重写。基本上,我有一个16个数字的板,我想循环遍历每个数字三次和我正在使用的四个函数(加,减,乘,取幂)。 1 + 2 + 3,2 * 3-4,3 ^ 4-5,9-4 ^ 3等,但没有操作顺序(第一次操作总是先完成)。
我想要的是概述如何在Objective-C中实现这一点。具体来说,Objective-C中的函数数组相当于什么?有没有一种简单的方法来实现选择器?用于带数字的循环的最佳结构是什么? NSInteger
的数组int
,NSArray
/ NSMutableArray
NSNumbers
的数组?
import random as rand
min = 0
max = 9
max_target = 20
maximum_to_calculate = 100
def multiply(x, y):
return x * y
def exponate(x, y):
return x ** y
def add(x, y):
return x + y
def subtract(x, y):
return x - y
function_array = [multiply, exponate, add, subtract]
board = [rand.randint(min, max) for i in xrange(0, 16)]
dict_of_frequencies = {}
for a in board:
for b in board:
for first_fun in function_array:
first_result = first_fun(a, b)
for c in board:
for second_fun in function_array:
final_result = second_fun(first_result, c)
if final_result not in dict_of_frequencies:
dict_of_frequencies[final_result] = 0
dict_of_frequencies[final_result] += 1
答案 0 :(得分:2)
Objective-C中构建函数数组的最方便的方法是使用Blocks:
typedef NSInteger (^ArithmeticBlock)(NSInteger, NSInteger);
ArithmeticBlock add = ^NSInteger (NSInteger x, NSInteger y){
return x + y;
};
ArithmeticBlock sub = ^NSInteger (NSInteger x, NSInteger y){
return x - y;
};
NSArray * operations = @[add, sub];
由于no great way要对NSNumber
执行算术运算,最好将基板的值创建并存储为基元,例如{{1}在一个普通的C数组中。如有必要,您可以稍后轻松将其打包 - NSInteger
为您提供@(boardValue)
。
答案 1 :(得分:0)
如果你想用直接的C函数指针来完成它,那么这样就可以了:
#include <stdio.h>
#include <math.h>
long add(int a, int b) {
return a + b;
}
long subtract(int a, int b) {
return a - b;
}
long multiply(int a, int b) {
return a * b;
}
long exponate(int a, int b) {
return pow(a, b);
}
int main(void) {
long (*mfunc[4])(int, int) = {add, subtract, multiply, exponate};
char ops[4] = {'+', '-', '*', '^'};
for ( int i = 0; i < 4; ++i ) {
printf("5 %c 9 = %ld\n", ops[i], mfunc[i](5, 9));
}
return 0;
}
并给出输出:
paul@MacBook:~/Documents/src$ ./rndfnc
5 + 9 = 14
5 - 9 = -4
5 * 9 = 45
5 ^ 9 = 1953125
paul@MacBook:~/Documents/src$
函数指针语法可能会有些错综复杂。 long (*mfunc[4])(int, int)
基本上转换为定义一个名为mfunc
的四元素数组,指向函数返回long
并使用两个int
类型的参数。
答案 2 :(得分:0)
Maddy是对的。无论如何,我只是为了它的乐趣试一试。 这从未见过编译器。所以请提前原谅我所有的拼写错误和轻微的语法错误。
#include <stdlib.h>
...
const int MIN = 0;
const int MAX = 9;
const int MAX_TARGET = 20;
const int MAX_TO_CALCULATE = 100;
...
- (int) multiply:(int)x with:(int)y { return x * y; }
- (int) exponate:(int)x with:(int)y { return x ^ y; }
- (int) add:(int)x to:(int)y { return x + y; }
- (int) substract:(int)x by:(int)y { return x - y; }
// some method should start here, probably with
-(void) someMethod {
NSArray *functionArray = [NSArray arrayWithObjects: @selector(multiply::), @selector(exponate::), @selector(add::), @substract(multiply::), nil]; // there are other ways of generating an array of objects
NSMutableArray *board = [NSMutableArray arrayWithCapacity:16]; //Again, there are other ways available.
for (int i = 0; i < 16; i++) {
[board addObject:@(arc4random() % (MAX-MIN) + MIN)];
}
NSMutableDictionary dictOfFrequencies = [[NSMutableDictionary alloc] init];
for (NSNumber a in board)
for (NSNumber b in board)
for (SEL firstFun in functionArray) {
NSNumber firstResult = @([self performSelector:firstFun withObject:a withObject:b]);
NSNumber countedResults = [dictOfFrequencies objectForKey:firstResult];
if (countedResults) {
[dictOfFrequencies removeObjectForKey:firstResult];
countedResults = @(1 + [countedResults intValue]);
} else {
countedResults = @1; // BTW, using the @ followed by a numeric expression creates an NSNumber object with the value 1.
}
[dictOfFrequencies setObject:countedResults forKey:firstResult];
}
}
好吧,让我在其他人之前添加一些评论。 :-) 没有必要客观c。你的python代码是迭代的,因此你可以在普通的C中实现它.Plain C可用于Objective C所在的地方。 如果你真的想在这里使用Objective-C那么你应该忘记你的python代码并在OOP风格的Objective-C中实现相同的逻辑(针对相同的结果)。我的代码确实试图尽可能地将您的代码翻译。因此,我的代码远非既没有好的风格,也没有可维护也没有适当的OOP。在你想到之前记住这一点,与python相比,ObjC很复杂: - )