2

我最近才进入 iphone 开发和 Objective-c 的世界,所以对于如何实现这样的东西我还是有点迷茫。

我有一个浮点数,我有一个浮点数可以落入的范围列表以及我应该返回的相应值,例如:

10.0 - 14.5 : 1.0
14.5 - 17.0 : 2.0
17.0 - 23.0 : 2.5
23.0 - 32.4 : 4.0

因此,如果我的浮点数是 15.12,我想返回 2.0。

使这个棘手的部分是范围列表很长,我有几个这样的范围列表需要从中进行选择,其中任何一个都可能需要稍后更改。至少可以说,简单地写几百或几千条if语句似乎是一个丑陋的解决方案。

4

2 回答 2

3

如果范围都是相邻的,您可以为此创建一个自定义集合类,并使用两个并行的数字数组来实现它。

第一个数组中的每个数字都是一个或两个范围的一端:

  • 10.0
  • 14.5
  • 17.0
  • 23.0
  • 32.4

第二个数组少一个数;这些数字是要映射到的值:

  • 1.0
  • 2.0
  • 2.5
  • 4.0

您搜索此集合的实现将包括将请求的键号与键数组中的每个数字及其后面的数字进行比较。实现线性搜索是最简单的,至少一开始是这样(您可以稍后在 Instruments 或 Shark 的指导下对其进行优化)。例如,假设这个对象被问到 20 次:

  • 10.0 ≤ 20 < 14.5?不。
  • 14.5 ≤ 20 < 17.0?不。
  • 17.0 ≤ 20 < 23.0?是的。

发现请求的键值在第三个范围内后,返回第三个值 (2.5)。

于 2010-08-24T07:54:57.420 回答
2

基本上你所描述的是模糊逻辑

我给你写了一个模糊逻辑规则类,它应该处理你想做的事情。

特征:

  • 您可以使用我提供的方法轻松添加自己的自定义规则。
  • 您可以使用单个检查值method并获得字符串结果(或者nil如果它不匹配任何规则)。
  • 由于它使用规则,您可以定义您希望的任何间隔时间。

添加新规则

[logic addRule:@"2.0" forLowerCondition:14.5 forUpperCondition:17.0];

示例输出(来自下面的代码):

Result for 15.20 is: 2.0

这是代码实现......

在你的主要:

FuzzyLogic *logic = [[FuzzyLogic alloc] initWithRule:@"1.0" forLowerCondition:10.0 forUpperCondition:14.5];

[logic addRule:@"2.0" forLowerCondition:14.5 forUpperCondition:17.0];
[logic addRule:@"2.5" forLowerCondition:17.0 forUpperCondition:23.0];

double input1 = 15.2f;

NSLog(@"Result for %.2lf is: %@", input1, [logic fuzzyResultForValue:input1]);

[logic release];

模糊逻辑.h:

#import <Foundation/Foundation.h>

@interface FuzzyLogic : NSObject {
    NSMutableArray *conditions;
}

- (id) initWithRule:(NSString*)result forLowerCondition:(double)lower forUpperCondition:(double)upper;
- (void) addRule:(NSString*)result forLowerCondition:(double)lower forUpperCondition:(double)upper;
- (NSString*) fuzzyResultForValue:(double)input;

@end

模糊逻辑.m:

#import "FuzzyLogic.h"

@implementation FuzzyLogic

enum {
    lowerIndex = 0,
    upperIndex,
    resultIndex
};

- (id) initWithRule:(NSString*)result forLowerCondition:(double)lower forUpperCondition:(double)upper {
    self = [super init];
    if (self != nil) {
        [self addRule:result forLowerCondition:lower forUpperCondition:upper];
    }
    return self;
}

- (void) addRule:(NSString*)result forLowerCondition:(double)lower forUpperCondition:(double)upper {

    NSArray *rule = [[NSArray alloc] initWithObjects:[NSString stringWithFormat:@"%lf",lower],[NSString stringWithFormat:@"%lf",upper],result,nil];

    if (conditions == nil) {
        conditions = [[NSMutableArray alloc] initWithObjects:rule,nil];
    } else {
        [conditions addObject:rule];
    }
}

- (NSString*) fuzzyResultForValue:(double)input
{
    NSString *returnable = nil;

    // Find the result
    for (NSArray *cond in conditions) {
        double lower = [[cond objectAtIndex:lowerIndex] doubleValue];
        double upper = [[cond objectAtIndex:upperIndex] doubleValue];
        if ( (input >= lower && input < upper) ) {
            returnable = [cond objectAtIndex:resultIndex];
            break;
        }   
    }

    if (returnable == nil) 
    { NSLog(@"Error: Input met no conditions!");}
    return returnable;
}

@end
于 2010-08-24T14:36:53.160 回答