我有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的冲突是双向的)。但是,当涉及到体育和计算机的冲突时它应该起作用,因为它只显示了一次。
我怎样才能正常工作? 如果这被认为是特定的道歉,我已经搞砸了几个星期,并且无论我采取何种方式,我都不会感到很喜欢。
答案 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])
{
你的逻辑将起作用。 (虽然有很多改进的机会,包括如上所述缩短内部循环)。