获取迭代总数,直到满足条件

时间:2011-12-04 14:32:22

标签: c# for-loop

for (int i= 0; i<10; i++)
{
    phi0 = phi0 * (L / L0);
    X0 = R * Math.Sin(2 * phi0) * Math.Cos(phi0);
    L0 = X0 * (1 + (Math.Pow(Math.Tan(phi0), 2)) / 10 - (Math.Pow(Math.Tan(phi0), 4)) / 72 + (Math.Pow(Math.Tan(phi0), 6)) / 208);
    if ((Math.Abs(L0 - L)) < (0.003 * Math.Sqrt(L)))
        break;
}

通常在2,3次迭代之后满足条件,但我需要一条消息来显示满足条件的迭代次数,以及它是否超过总数10。

如果有什么可以解释的话可以自由地问。

谢谢!

6 个答案:

答案 0 :(得分:3)

i的声明移到循环之外,以便在它之后可用。

然后您可以在循环后立即检查其值。如果是<10,则循环退出退出条件。如果它恰好是10,那么最后一次允许的迭代(使用i==9)不符合退出条件。

答案 1 :(得分:2)

i的声明移到循环之外,之后可以使用它的值。请记住,i的值比自从0开始时使用的迭代次数少一个 - 实际上因为你没有在循环中的任何表达式中使用i ,您可能希望它从1到10而不是0到9.

请注意,您也可以进行小幅优化,以加快速度。编译器可能会为您执行此操作,但您可以通过将tan(phi0)的中间计算存储在本地变量中来确保。

int i = 1;
for (; i<=10; i++)
{
    phi0 = phi0 * (L / L0);
    var tanPhi0 = Math.Tan(phi0);
    X0 = R * Math.Sin(2 * phi0) * Math.Cos(phi0);
    L0 = X0 * (1 + (Math.Pow(tanPhi0, 2)) / 10 - (Math.Pow(tanPhi0, 4)) / 72 + (Math.Pow(tanPhi0, 6)) / 208);
    if ((Math.Abs(L0 - L)) < (0.003 * Math.Sqrt(L)))
        break;
}

if (i <= 10)
{
    Console.WriteLine( "The loop took {0} iterations", i );
}
else
{
    Console.WriteLine( "It did not converge" );
}

事实上,如果多次执行此操作,您可能需要更进一步,并尝试分阶段计算tan(phi0)的权限,而不是每次都调用Pow。我在这里假设乘法比调用Pow方法更快,这似乎是合理的,但你需要测试它以确保。每次都没有理由计算误差限制。

var epsilon = 0.003 * Math.Sqrt(L);
int i = 1;
for (; i<=10; i++)
{
    phi0 = phi0 * (L / L0);
    var tanPhi0 = Math.Tan(phi0);
    var tanPhi0_2 = tanPhi0 * tanPhi0;
    var tanPhi0_4 = tanPhi0_2 * tanPhi0_2;
    var tanPhi0_6 = tanPhi0_4 * tanPhi0_2;
    X0 = R * Math.Sin(2 * phi0) * Math.Cos(phi0);
    L0 = X0 * (1 + tanPhi0_2 / 10 - tanPhi0_4 / 72 + tanPhi0_6 / 208);
    if ((Math.Abs(L0 - L)) < epsilon)
        break;
}

if (i <= 10)
{
    Console.WriteLine( "The loop took {0} iterations", i );
}
else
{
    Console.WriteLine( "It did not converge" );
}

答案 2 :(得分:1)

在循环之外(之前)声明i,之后你可以用它来做任何事情。

答案 3 :(得分:1)

只需添加一个简单的计数器:

int iterCount = 0;
for (int i= 0; i<10; i++)
{
    iterCount++;
    ϕ0 = ϕ0 * (L / L0);
    X0 = R * Math.Sin(2 * ϕ0) * Math.Cos(ϕ0);
    L0 = X0 * (1 + (Math.Pow(Math.Tan(ϕ0), 2)) / 10 - (Math.Pow(Math.Tan(ϕ0), 4)) / 72 + (Math.Pow(Math.Tan(ϕ0), 6)) / 208);
    if ((Math.Abs(L0 - L)) < (0.003 * Math.Sqrt(L)))
        break;

}
MessageBox.Show("Number of iterations: " + iterCount);

答案 4 :(得分:0)

在循环之前声明一个布尔变量(bool done = false),如果满足条件则将其设置为true。 在您休息之前,打印i的值以获得迭代次数。

 if ((Math.Abs(L0 - L)) < (0.003 * Math.Sqrt(L))) {
       done = true;
       Console.WriteLine(i);
       break;
 }

如果循环后done == false,则表示循环中未满足条件。

答案 5 :(得分:0)

你基本上只需要扩展变量i的范围吧?这可以这样做:

int i;
for (i = 0; i<10; i++)
{
  //Do stuff
}
Console.WriteLine("i: " + i);

变量i仍然在循环外的范围内,并且在循环中断时保持它具有的值;如果它根本没有破坏,则为10。

希望这有帮助。