【问题标题】:forward and backward search algorithm on an array数组上的前向和后向搜索算法
【发布时间】:2014-03-11 20:11:32
【问题描述】:

我正在研究一个简单的算法问题以供练习,我试图找出为什么在大约 20% 的测试用例中它会失败。因此,问题是,给定一个整数数组,找到数组中所有有效整数的平均值。

一个 int 是有效的,如果

  1. 大于等于-273
  2. 前两个或后两个整数中的至少一个距离当前整数两点

如果 int 无效,则不应将其包含在计算平均值中。另外,我不相信问题希望解决方案是循环的(不确定虽然只是在写这个时考虑过,所以会尝试),即如果你在第一个 int array[0],那么没有前两个 int而最后两个是循环数组中的前两个。

我的策略总结在下面的代码中:

public double averageTemperature(int[] measuredValues)
{
    Queue<int> qLeft = new Queue<int>(2);
    Queue<int> qRight = new Queue<int>(2);

    double sum = 0d;
    int cnt = 0;

    for (int i = 0; i < measuredValues.Length; i++)
    {
        if (measuredValues[i] < -273)
            continue;
        if (qLeft.Count == 3)
            qLeft.Dequeue();
        for (int j = i + 1; j < measuredValues.Length; j++)
        {
            if (qRight.Count == 2)
            {
                break;
            }
            qRight.Enqueue(measuredValues[j]);
        }

        if (b(qLeft, qRight, measuredValues[i]) == true)
        {
            sum += measuredValues[i];
            cnt++;
            qLeft.Enqueue(measuredValues[i]);
        }


        qRight.Clear();
    }

    if (cnt > 0)
        return sum / cnt;
    return -300.0;
}
bool b(Queue<int> a, Queue<int> b, int c)
{
    foreach (int q in a)
    {
        if (Math.Abs(q - c) <= 2)
            return true;
    }
    foreach (int w in b)
    {
        if (Math.Abs(w - c) <= 2)
            return true;
    }
    return false;
}

但是,对于这个测试用例,我的策略失败了

{-13, 12, -14, 11, -15, 10, -16, 9, -17, 8, -18, 7, 6, -19, 5, -400, -400, 4, -390, -300, -270, 3, -12, 3, 2}

我不明白为什么。我错过了一些明显的东西?我知道它们可能是解决此问题的另一种更有效的方法,但我不想尝试它们,直到我知道为什么我的“幼稚”方法不起作用。

好吧,我终于明白了为什么要感谢你们。这是我修改后的代码,供那些可能觉得有用的人使用:

public double averageTemperature(int[] measuredValues)
    {
        Queue<int> qLeft = new Queue<int>(2);
        Queue<int> qRight = new Queue<int>(2);

        double sum = 0d;
        int cnt = 0;


        for (int i = 0; i < measuredValues.Length; i++)
        {
            if (qLeft.Count == 3)
                qLeft.Dequeue();
            for (int j = i + 1; j < measuredValues.Length; j++)
              {
                if (qRight.Count == 2)
                {
                    break;
                }
                qRight.Enqueue(measuredValues[j]);
            }

            if (isValid(qLeft, qRight, measuredValues[i]) == true)
            {
                sum += measuredValues[i];
                cnt++;

            }
            qLeft.Enqueue(measuredValues[i]);
            qRight.Clear();
        }

        if (cnt > 0)
            return sum / cnt;
        return -300.0;
    }
    bool isValid(Queue<int> a, Queue<int> b, int c)
    {

        foreach (int q in a)
        {
            if (c >=-273 && Math.Abs(q - c) <= 2)
                return true;
        }
        foreach (int w in b)
        {
            if (c >=-273 && Math.Abs(w - c) <= 2)
                return true;
        }
        return false;
    }

【问题讨论】:

  • 是“273”还是“-273”?从您的测试用例中,我猜它会是“-273”。
  • 我不确定你所说的“两点”是什么意思,但是你给出的数据集不包含元素后面或前面两个元素==当前元素的值+ /- 2.
  • @ormaaj 让我解释一下。 -13 是有效的,因为至少有一个元素距离最多 2 个元素,最多比 -13 大或小 2 个点。所以 12 显然不是距离 -13 2 点,而是 -14 距离 -13 仅 1 点。所以 -13 是有效的。如果 -13 前面的两个元素都 > +/- 2 点,则 -13 将无效。

标签: c# arrays algorithm search iteration


【解决方案1】:

在比较时尝试从嵌套 for() 循环中的同一点开始。像这样:运行它会得到什么?

public double averageTemperature(int[] measuredValues)
{
Queue<int> qLeft = new Queue<int>(2);
Queue<int> qRight = new Queue<int>(2);

double sum = 0d;
int cnt = 0;

for (int i = 0; i < measuredValues.Length; i++)
{
    if (measuredValues[i] < -273)
        continue;
    if (qLeft.Count == 3)
        qLeft.Dequeue();
    for (int j = 0; j < measuredValues.Length; j++)
    {
        if (qRight.Count == 2)
        {
            break;
        }
        qRight.Enqueue(measuredValues[j]);
    }

    if (b(qLeft, qRight, measuredValues[i]) == true)
    {
        sum += measuredValues[i];
        cnt++;
        qLeft.Enqueue(measuredValues[i]);
    }


    qRight.Clear();
}

if (cnt > 0)
    return sum / cnt;
return -300.0;
}
bool b(Queue<int> a, Queue<int> b, int c)
{
foreach (int q in a)
{
    if (Math.Abs(q - c) <= 2)
        return true;
}
foreach (int w in b)
{
    if (Math.Abs(w - c) <= 2)
        return true;
}
return false;
}

是不是每个方向都加一个,让你们两个像以前一样远离?

【讨论】:

  • 队列右侧在当前 int 的右侧最多应该有两个 int。所以从 0 开始肯定行不通
  • 然后从 i + 2 而不是 i + 1 开始,看看效果如何。
【解决方案2】:

只有当数组中的当前值有效时,您才将排队进入 qLeft,但这是不对的。您需要在由 i 控制的外部 for 循环的每次迭代中加入 qLeft。

见以下代码:

for (int i = 0; i < measuredValues.Length; i++)
{
    if (measuredValues[i] < -273)
        continue;
    if (qLeft.Count == 3)
        qLeft.Dequeue();
    for (int j = i + 1; j < measuredValues.Length; j++)
    {
        if (qRight.Count == 2)
        {
            break;
        }
        qRight.Enqueue(measuredValues[j]);
    }

    if (b(qLeft, qRight, measuredValues[i]) == true)
    {
        sum += measuredValues[i];
        cnt++;
    }

    qLeft.Enqueue(measuredValues[i]); // YOU NEED TO ENQUEUE INTO qLeft EACH TIME REGARDLESS OF IT IS VALID OR INVALID
    qRight.Clear();
}

【讨论】:

  • 也试过了,所有无效的整数都应该在计算平均值之前被丢弃。将无效的 int 添加到队列左侧会扭曲结果
  • 无效的整数总是在 b() 方法中被丢弃。在条件 1(
猜你喜欢
  • 2016-05-23
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 2015-11-09
相关资源
最近更新 更多