数组上的前向和后向搜索算法

时间:2014-02-13 05:25:16

标签: c# arrays algorithm search iteration

我正在研究一个简单的算法问题,我试图弄清楚为什么大约20%的测试用例失败了。因此,问题在于,一组int就能找到数组中所有有效整数的平均值。

如果

,则int有效
  1. 大于或等于-273
  2. 前两个或后两个整数中的至少一个是距离当前一个
  3. 两个点

    如果int无效,则不应包括在计算平均值中。另外,我不相信问题想要解决方案是循环的(不确定虽然只是在写这个时会想到它所以会尝试)即即使你在第一个int数组[0],那么之前没有两个整数而后两个是循环数组中的前两个。

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

    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;
        }
    

2 个答案:

答案 0 :(得分: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;
}

是否每个方向都添加一个,就像你以前一样把你带走两个?

答案 1 :(得分:0)

只有当数组中的当前值有效时才进入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();
}