比较数组中的对象以查找时间表中的事件冲突

时间:2015-02-17 15:09:48

标签: ios objective-c arrays comparison

我有4个可在学校时间表上显示的活动对象。我需要检索一个彼此冲突的事件数组,即一个事件的开始时间在另一个事件的开始和结束时间之间。为了首先获得算法,我使用int代替NSDate。

 Event *event = [[Event alloc] init];
    event.courseName = @"Maths";
    event.room = @"405";
    event.startTime = [NSNumber numberWithInt:8];
    event.endTime = [NSNumber numberWithInt:10];
    [eventsStore addObject:event];

    Event *event2 = [[Event alloc] init];
    event2.courseName = @"English";
    event2.room = @"510";
    event2.startTime = [NSNumber numberWithInt:10];
    event2.endTime = [NSNumber numberWithInt:12];
    [eventsStore addObject:event2];

    Event *event3 = [[Event alloc] init];
    event3.courseName = @"Computing";
    event3.room = @"220";
    event3.startTime = [NSNumber numberWithInt:11];
    event3.endTime = [NSNumber numberWithInt:14];
    [eventsStore addObject:event3];

    Event *event4 = [[Event alloc] init];
    event4.courseName = @"Sports";
    event4.room = @"000";
    event4.startTime = [NSNumber numberWithInt:13];
    event4.endTime = [NSNumber numberWithInt:15];
    [eventsStore addObject:event4];

以下是我目前发现冲突的原因:

 int clashCounter = 0;
    Event *curEv = nil, *otherEv = nil;
    for(int i = 0; i < [eventsStore count]; i++)
    {

        curEv = [eventsStore objectAtIndex:i];


        for (int j = 0; j < [eventsStore count]; j++)
        {
            if (j!=i && ![curEv.clashList containsObject:otherEv])
            {
                otherEv = [eventsStore objectAtIndex:j];
                if (curEv.startTime < otherEv.endTime && otherEv.startTime < curEv.endTime)
                {
                    clashCounter++;
                    NSLog(@"Clash: %@ clashes with %@", curEv.courseName, otherEv.courseName);
                    [curEv.clashList addObject:otherEv];
                }
            }
        }
    }

首先创建两个空的Event对象。将循环遍历eventsStore数组中的每个事件,将curEv设置为objectAtIndex。然后循环遍历每个不是curEv且在其数组中没有otherEv的eventsStore数组对象。 (每个Event对象包含一个名为clashList的数组,用于与之冲突的事件)。如果是冲突,则将otherEv添加到curEv。

当我运行它时,我得到:

ClashTest[3393:134117] Clash: English clashes with Computing
ClashTest[3393:134117] Clash: Computing clashes with English
ClashTest[3393:134117] Clash: Sports clashes with Computing

这表明事件冲突被拾取但是它在第一个实例中存储了一个副本(英语与Computing的冲突是双向的)。但是,当涉及到体育和计算机的冲突时它应该起作用,因为它只显示了一次。

我怎样才能正常工作? 如果这被认为是特定的道歉,我已经搞砸了几个星期,并且无论我采取何种方式,我都不会感到很喜欢。

3 个答案:

答案 0 :(得分:0)

我相信您可以使用哈希映射来存储冲突,在第一个for循环之前定义它

NSMutableDictionary* clashes = [[NSMutableDictionary alloc] init];

现在当你找到碰撞(你正在记录它的地方)时,检查碰撞是否已经存在两种方式,如果没有,将它添加到碰撞字典中,如下所示(但你应该有一些唯一的事件ID,I& #39;我假设它是一个int例如

NSString* firstHashKey = [NSString stringWithFormat:@"%d", curEv.Id];
NSString* secondHashKey = [NSString stringWithFormat:@"%d", otherEv.Id];

if (([clashes valueForKey:firstHashKey] == nil) && ([clashes valueForKey:secondHashKey] == nil)) {
    clashes[firstHashKey] = @[ curEv, otherEv ];
}
else {
    // It is already added to the clashes dictionary so no need to do it
}

现在,当您想要打印所有冲突时,您只需执行以下操作

for (NSString* key in clashes.allKeys) {
    NSArray* value = clashes[key];
    Event* firstEvent = value[0];
    Event* secondEvent = value[1];
    NSLog(@"Clash: %@ clashes with %@", firstEvent.name, secondEvent.name);
}

答案 1 :(得分:0)

您可以将第二个循环更改为以j = i + 1开头(并且第一个循环停止在i&lt; [eventsStore count] - 1)。然后,您将只查看检查后的元素。

答案 2 :(得分:0)

代码中的问题是在内部循环中初始化otherEvent ...

    for (int j = 0; j < [eventsStore count]; j++)
    {
        if (j!=i && ![curEv.clashList containsObject:otherEv]) // <-- look
        {
            // this happens too late to properly check the condition above
            otherEv = [eventsStore objectAtIndex:j];

像这样改变......

    for (int j = 0; j < [eventsStore count]; j++)
    {
        otherEv = [eventsStore objectAtIndex:j];
        if (j!=i && ![curEv.clashList containsObject:otherEv])
        {

你的逻辑将起作用。 (虽然有很多改进的机会,包括如上所述缩短内部循环)。