我有我的电线交叉的地方(或者我没有足够的睡眠).我需要一个双向的循环,并且我目前代码只是普通的丑陋。

问题:我正在沿着线性datastructre使用索引。我有一个起始指数,可以说,120人。我要运行的交流为双向的。

例如:120,121,119,122,118,123,117,...

我有一个停止标准需要满足的每个方向分开。如果这是满足一个方向,我只是想来碰到的另一个方向,如果两个都得到满足,我需要退出的循环。此外,我需要停止,如果下一个指数是无效的(端的数据结构,说比0或大于200).

例如:停止执行在116倒退和130:120,121,119,122,118,123,117,124,116,(break),125,126,127,128,129,130.

跑进一个方向的第一,那么另一个不幸的是不是一个选项。

我目前代码是普通的丑陋.这是一个很大的纹没有包含任何"生产"的代码。只迭代的逻辑:

  int start_idx = 120;
  int forward_idx = start_idx;
  int backward_idx = start_idx;

  bool next_step_forward = true; //should next step be forward or backward?

  int cur_idx;
  while(backward_idx >= 0 || forward_idx >= 0)
  {
    if(next_step_forward   //if we should step forward
      && forward_idx >= 0) //and we still can step forward
    {
      cur_idx = ++forward_idx;

      if(forward_idx >= 200) //200 is fictive "max index"
      {
        next_step_forward = false;
        forward_idx = -1; //end of data reached, no more stepping forward
        continue;
      }

      if(backward_idx >= 0)
      {
        next_step_forward = false;
      }
    }
    else if(!next_step_forward 
            && backward_idx >= 0)
    {
      cur_idx = --backward_idx;
      if(backward_idx < 0) //beginning of data reached, no more stepping backward
      {
        next_step_forward = true;
        continue;
      }

      if(forward_idx >= 0)
      {
        next_step_forward = true;
      }
    }
    else
    {
      next_step_forward = !next_step_forward; //ever hit?, just security case
      continue; 
    }

    //loop body
    //do something with cur_idx here

    if(stoppingCriterionMet())
    {

      if(cur_idx > start_idx)
      { //this was a forward step, stop forward stepping
        forward_idx = -1;
      }
      else
      { //this was backward step, stop backward stepping
        backward_idx = -1;
      }
    }
  }

我错过了什么?任何提示赞赏。谢谢。

编辑1:有很多非常好的答案,其中把"做一些与cur_idx"成一个单独的功能。虽然这是一个完美的想法我的问题,我更喜欢把迭代码在其他地方,离开的富有成效的代码。我有一个很长的算法和想要分裂它,之后它完成,以尽量减少rearangement的工作。

有帮助吗?

解决方案

这么发生了,我编写这个问题几乎今天。和我使用了C#迭代的功能做到这一点。但我认为你想要一个更通用的解决方案。

如果您使用的语言,你可以建立自己的迭代(C++、Java,C#),这很容易。你只要做一个自定义迭代,最初吐出数从开始的中心。然后你给迭代的一个额外的功能告诉它停止运行在目前的方向。

如果你正在做这样的事情在C(它看起来C我),可以模仿这一结构包含的迭代态和功能,你的呼叫要步骤,它进或阻止它。

其他提示

这个怎么样?

void do_loop(SomeType *arr, int start, int low, int high, int arr_max)
{
    int downwardIndex, upwardIndex;
    downwardIndex = upwardIndex = start;
    while (downwardIndex > 0 && upwardIndex < arr_max) {
        if (downwardIndex < low && upwardIndex > high) {
            break;
        }
        if (downwardIndex > low) {
            processElement(arr[downwardIndex]);
            downwardIndex--;
        }
        if (upwardIndex < high) {
            processElement(arr[upwardIndex]);
            upwardIndex++;
        }
    }
}

第一次通过在黑客这一(假定C-适应所需的其他语言,但这些概念基本上是中性语言):

void pass1(int start_x, int lo_limit, int hi_limit)
{
    assert(start_x >= lo_limit && start_x <= hi_limit);
    int lo_x = start_x - 1;
    int hi_x = start_x + 1;

    Process(start_x);
    if (StopCriterion(start_x))
        return;  // Is that correct?

    while (lo_x >= lo_limit && hi_x <= hi_limit)
    {
        Process(lo_x);
        if (StopCriterion(lo_x))
            lo_x = lo_limit - 1;
        else
            lo_x--;
        Process(hi_x);
        if (StopCriterion(hi_x))
            hi_x = hi_limit + 1;
        else
            hi_x++;
    }
    while (lo_x >= lo_limit)
    {
        Process(lo_x);
        if (StopCriterion(lo_x))
            lo_x = lo_limit - 1;
        else
            lo_x--;
    }
    while (hi_x <= hi_limit)
    {
        Process(hi_x);
        if (StopCriterion(hi_x))
            hi_x = hi_limit + 1;
        else
            hi_x++;
    }
}

还不清楚会发生什么情况如果启动位置相匹配的停止的标准。应该搜索完全停止,或它应该继续向上或向下的,或这两种方法。我选择了'完全停止'的,但一种情况下可能作出的任何选项列出。在这种情况下的"双方",你甚至不会打扰到停止运行标准检查。

我也选择了去做下之前的上方向;这显然是平凡逆转。订单的最后两个循环并不重要,因为如果两个方向的终止在同一次迭代,既没有后环执行;如果只有一个方向是终止,相对应的循环不会执行,在所有-只有其他会的。

因为那里仍然重复代码中有:

void pass2(int start_x, int lo_limit, int hi_limit)
{
    assert(start_x >= lo_limit && start_x <= hi_limit);
    int lo_x = start_x - 1;
    int hi_x = start_x + 1;

    Process(start_x);
    if (StopCriterion(start_x))
        return;  // Is that correct?

    while (lo_x >= lo_limit && hi_x <= hi_limit)
    {
        Process_lo(&lo_x, lo_limit);
        Process_hi(&hi_x, hi_limit);
    }
    while (lo_x >= lo_limit)
        Process_lo(&lo_x, lo_limit);
    while (hi_x <= hi_limit)
        Process_hi(&hi_x, hi_limit);
}

void Process_lo(int *lo_x, int lo_limit)
{
    Process(*lo_x);
    if (StopCriterion(*lo_x))
        *lo_x = lo_limit - 1;
    else
        *lo_x--;
}

void Process_hi(int *hi_x, int hi_limit)
{
    Process(*hi_x);
    if (StopCriterion(*hi_x))
        *hi_x = hi_limit + 1;
    else
        *hi_x++;
}

能见度的控制(静态功能)等左出详细的执行情况的语言。

这是我想的办法,它在C#:

const int UPPER_BOUND = 200;
const int LOWER_BOUND = 0;
const int START = 120;
bool foundlower = false, foundupper = false;
int upper, lower; 
upper = lower = START;

while (!foundlower || !foundupper) {
    if (!foundlower) {
        if (--lower <= LOWER_BOUND) foundlower = true;
        if (stoppingCriterionMet(lower)) foundlower = true;
    }

    if (!foundupper) {
        if (++upper >= UPPER_BOUND) foundupper = true;
        if (stoppingCriterionMet(upper)) foundupper = true;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top