永远迷失在 if、while 和 foreach 语句中 - 无法获得适当的条件来运行
Posted
技术标签:
【中文标题】永远迷失在 if、while 和 foreach 语句中 - 无法获得适当的条件来运行【英文标题】:Forever lost in if, while and foreach statement - cannot get the appropriate condition to run 【发布时间】:2016-03-30 00:11:38 【问题描述】:我在这个问题上花了相当多的时间,它很基本,但很快就失控了。
因为它相当令人困惑,所以我将发布我想要它做什么以及它实际做什么
目标
如果一个主管忙,它将转到下一个,如果他们都忙,它将显示一条消息“对不起,所有主管都忙”。对所有员工也是如此。
方法
我希望该方法读取所有主管,如果一个不忙则继续向下,然后我希望它读取所有员工,如果一个不忙则继续向下。
然后它会读取员工是否具有适当的技能以及是否已经取得成功,以避免同一个人被分配相同的工作。
如果到目前为止一切正常,它会检查主管是否被占用,如果是,它会恢复并更改主管。
然后它为员工分配信息,同时为主管分配一些信息并检查“成功”条件。
从这里开始有点草率了,正如你所看到的,我已经放置了许多布尔语句来简单地让程序退出循环并退出它。
在所有这一切之后,程序分配了工作,到目前为止,它在合理的程度上工作,但我希望有一条消息指出,如果所有主管都忙,则无法分配更多工作。
我过去曾在 foreach 语句后使用 MessageBox.Show
,但如果一位主管很忙,它会显示我不想要的消息。
代码
分配作业的方法
bool finishLast = false;
bool successFirst = false;
while (successFirst != true)
foreach (Supervisor sup in supervisors)
bool failure = false;
while (failure != true)
foreach (Employee emp in employees)
if (emp.Busy == false && emp.Skills.HasFlag(_skillRequired) && successFirst == false)
if (sup.SupervisorOccupied == false)
successFirst = true;
emp.EmployeeWorkload = _jobName;
emp.ShiftsLeft = _shiftsLeft;
emp.Busy = true;
sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
sup.ShiftsLeft = _shiftsLeft;
sup.SupervisorOccupied = true;
else if (emp.Busy == true)
failure = true;
if (failure == true)
finishLast = true;
if (finishLast == true)
successFirst = true;
当然,如果有人能想到一个更简单的方法,我会接受想法。
编辑 1
这不是一个多线程系统,是的,emp.Busy
和 sup.SupervisorOccupied
在技术上是一样的,它们都在 same class
中,所以是的,sup 可以继承 emp.Busy
。
【问题讨论】:
您能否更新您的问题并添加一个真正的“目标”?你首先描述你在做什么,而不是结果应该是什么。我猜您正在为用户分配工作,但我不完全清楚应该如何发生以及您的出发点是什么。 重新阅读您的代码后,您似乎想要执行以下操作: 找到一个可用的主管。找到具有该工作技能的可用员工。将工作分配给员工,并指派主管监督该员工的工作。如果这是正确的,那么您根本就不应该有嵌套循环。 我建议你删除所有 while 循环而不是必需的布尔值,因为它们非常令人困惑 我也很难理解这段代码的含义,这本身就是一个问题,就像它明显缺乏正确性一样。有几件事会有所帮助。首先,停止if (x != true)
等。等式产生一个布尔值,但布尔值已经布尔值!如果您的意思是if (x == true)
或while (x == true)
,只需说if (x)
或while (x)
。而不是if (x == false)
-- 如果 x 是真的,那么 x 是假的 -- 比如说 if (!x)
-- 如果 x 的反面是真的。
第二,把这个东西分解成更小的方法,每个方法在问题的条件下做一些事情。就像 Lasse 所说,如果问题的一部分是要找到一个可用的主管,那么应该有一个方法 FindAvailableSupervisor
如果没有这样的主管,则返回一个主管或 null。编写那个方法,测试一下,现在你有了一个子系统,你可以依靠它来解决更大的问题。尝试根据业务领域编写问题陈述,而不是您打算如何编写代码。
【参考方案1】:
我认为这样的事情应该可行:
bool assigned = false;
foreach (Supervisor sup in supervisors)
if (!sup.SupervisorOccupied)
foreach (Employee emp in employees)
if (!emp.Busy && emp.Skills.HasFlag(_skillRequired))
assigned = true;
emp.EmployeeWorkload = _jobName;
emp.ShiftsLeft = _shiftsLeft;
emp.Busy = true;
sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
sup.ShiftsLeft = _shiftsLeft;
sup.SupervisorOccupied = true;
break;
if (assigned)
break;
如果最后“assigned == false”,则没有可用的员工(实际上缺少一些代码,因此无法运行,但理论上它应该做你想做的事!)。
【讨论】:
太好了,这似乎奏效了,我知道我已经把它复杂化了,但是在凌晨 4 点,一个人无法重新制定想法,我会在短时间内奖励你的答案跨度> 好丹尼很乐意提供帮助。还要看看其他答案,因为您必须有机会选择实施,请“接受”答案,谢谢【参考方案2】:下面是你应该如何编写代码:
var availableSupervisor = supervisors
.FirstOrDefault(supervisor => !supervisor.SupervisorOccupied);
if (availableSupervisor == null)
return;
var availableEmployee = employees
.FirstOrDefault(employee => !employee.Busy && employee.Skills.HasFlag(_skillRequired));
if (availableEmployee == null)
return;
availableEmployee.EmployeeWorkload = _jobName;
availableEmployee.ShiftsLeft = _shiftsLeft;
availableEmployee.Busy = true;
availableSupervisor.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
availableSupervisor.ShiftsLeft = _shiftsLeft;
availableSupervisor.SupervisorOccupied = true;
【讨论】:
其实我不太喜欢用Exceptions来控制程序流程。即使他说这不是一个多线程环境,我认为很容易发生这样的一段代码,执行循环(可能在那里花费一段时间)稍后移动到一个计时器中:在这种情况下管理异常会肯定比更新一个外部“状态”对象更复杂,该对象还可以携带有关操作进度的信息(以及最终结果 - “分配的”布尔值 - 显然) 虽然从长远来看,您的答案看起来是最有效的,但我选择了一个适合我工作环境的答案,同时我很感谢您的 cmets 和答案,请不要认为我有忽略了你的努力。谢谢。 @Lasse:如果将.Where(supervisor => !supervisor.SupervisorOccupied).FirstOrDefault()
替换为.FirstOrDefault(supervisor => !supervisor.SupervisorOccupied)
,这段代码会更简洁一些。显然你可以对availableEmployee
做同样的事情。
@LeonardoSpina:我同意你的观点,我不喜欢使用异常,但我确实认为 Lasse 的方法远远优于 OP 的现有方法。异常可以用循环代替。 Danny,我强烈建议你采用 Lasse 的方法;您对嵌套循环的使用更难遵循。嵌套循环方法的效率也较低,但这很容易在员工循环下使用额外的 break 语句来解决(即,如果您找不到第一个主管的空闲员工,也不要费心检查下一个主管)。
异常只是处理这些情况的一种方法,返回语句等等,还有很多其他方法来处理这些退出点。以上是关于永远迷失在 if、while 和 foreach 语句中 - 无法获得适当的条件来运行的主要内容,如果未能解决你的问题,请参考以下文章
在 foreach 循环中的 if 语句中的 while 循环...无法正常工作
PHP - If/else, for, foreach, while - 没有花括号?