C 计算三个嵌套for循环的总体进度(%)
我有三个嵌套for循环,每个循环显然都有一个限制。要计算三个for循环中任何一个的进度,我需要做的就是将当前迭代除以循环将进行的总迭代次数。但是,考虑到有三种不同的for循环,如何计算完成的总体百分比C 计算三个嵌套for循环的总体进度(%),c,for-loop,progress,C,For Loop,Progress,我有三个嵌套for循环,每个循环显然都有一个限制。要计算三个for循环中任何一个的进度,我需要做的就是将当前迭代除以循环将进行的总迭代次数。但是,考虑到有三种不同的for循环,如何计算完成的总体百分比 int iLimit = 10, jLimit = 24, kLimit = 37; for (int i = 0; i < iLimit; i++) { for (int j = 0; j < jLimit; j++) { for (int k = 0; k
int iLimit = 10, jLimit = 24, kLimit = 37;
for (int i = 0; i < iLimit; i++) {
for (int j = 0; j < jLimit; j++) {
for (int k = 0; k < kLimit; k++) {
printf("Percentage Complete = %d", percentage);
}
}
}
记住百分比是100的一部分 要获得100,您需要执行例如
(iLimit*jLimit*kLimit)/(iLimit*jLimit*kLimit)*100
循环的每次迭代都会占用整个循环的1/(iLimit*jLimit*kLimit)
部分
要获得百分比,“简单地”执行以下操作:
请记住在循环之前声明并初始化
计数器变量。如果我正确理解您的问题,那么我认为每个级别的计数器变量(即I
,j
,k
)在%年龄公式中应该具有不同的权重。让我解释一下我的意思:j
的每个增量对应于最内层循环的kLimit
迭代。因此,如果您只有一个嵌套级别(假设使用i
的最外层循环不存在),那么循环迭代的总数将是kLimit*jLimit
,并且百分比:
百分比=(100.0*(j*kLimit+k+1))/(浮动)(kLimit*jLimit)
你有主意吗?很容易将这个概念推广到所需的嵌套级别。我希望你能很好地为你的案子找到所需的方程式。无论如何,这里是最后的公式:
percentage=100.0*(kLimit*(i*jLimit+j)+k+1)/(iLimit*jLimit*kLimit)
您可以轻松计算“每个内部循环的百分比变化”
注意,这在数学上相当于1/(iLimit*jLimit*kLimit)
,但是如果iLimitjLimitkLimit足够大,则会出现溢出和意外行为。1.0/…仍有可能出现下溢。。。方法,但可能性要小得多
int iLimit = 10, jLimit = 24, kLimit = 37;
const double percentChange = 1.0 / iLimit / jLimit / kLimit;
double percentage = 0;
for (int i = 0; i < iLimit; i++) {
for (int j = 0; j < jLimit; j++) {
for (int k = 0; k < kLimit; k++) {
percentage += percentChange;
printf("Percentage Complete = %d\n", (int)(percentage * 100));
}
}
}
int-iLimit=10,jLimit=24,kLimit=37;
常数双百分比变化=1.0/iLimit/jLimit/kLimit;
双倍百分比=0;
for(int i=0;i
试试这个:
int iLimit = 10, jLimit = 24, kLimit = 37;
float percentage;
for (int i = 0; i < iLimit; i++) {
for (int j = 0; j < jLimit; j++) {
for (int k = 0; k < kLimit; k++) {
percentage = ((k+1) + j * kLimit + i*jLimit*kLimit)/(float)(iLimit*jLimit*kLimit) * 100;
printf("Percentage Complete = %f\n", percentage);
}
}
}
这样,当你知道i,j,k时,你就可以找到百分比,而无需迭代循环。
因此,您可以将一个O(iLimit*jLimit*kLimit)问题简化为一个O(1)问题。循环的总数是iLimit*jLimit*kLimit
,因此,如果在内部循环中有一个递增的百分比,您可以直接打印
100 * percentage / (iLimit * jLimit * kLimit)
由于您正在使用%d
打印百分比,因此可以将所有内容限制为整数计算。(它避免了在第一步中看到无意义的“精确”值,如0.011261
)
如果要查看正确舍入的值,还可以使用以下选项:
printf("Percentage Complete = %d%%\r", (counter*200+iLimit * jLimit * kLimit) /
(2 * iLimit * jLimit * kLimit));
最后的\r
是一个很小的改进,因此每一行都将叠加上一行。执行printf
语句的次数iLimit*jLimit*kLimit
应该很容易从中计算百分比。我在第三个for循环中放置了一个计数器变量(int k=0
)为了表示调用printf的次数,然后将其除以(iLimit*jLimit*kLimit)
,但百分比似乎会波动,并且永远不会超过35.53%。计算通过每个循环的每个单独过程所完成的百分比(例如,最里面的循环是1/(10*24*37)对于循环的每次通过。同样,中间循环的每次通过循环为1/(10*24),外部循环的每次通过循环为1/10。然后对于任何特定循环,完成的总百分比为(i*(1/(10)+j*(1/(10*24)+k*(1/(10*24*37))之和*100.当然,所有的数字和数学都应该使用浮点而不是整数来执行。如果每次迭代都表示1/(iLimit*jLimit*kLimit)
,那么肯定是count/(iLimit*jLimit*kLimit)*100
这个数学,从:'(iLimit*jLimit*kLimit)/(iLimit*jLimit*kLimit*kLimit)开始*100'是不正确的,所以downvoted谢谢你的回答,我没有立即意识到1/(iLimit*jLimit*kLimit)
代表一次迭代,因此无法计算出它背后的百分比。该方法对循环的每次迭代执行完整的百分比计算(即4次乘法+1次除法+1次加法)。一种优化方法是预计算每次迭代的增量百分比,因此在循环的每次迭代中,只有1次加法。参见Daniel的answer@LoPiTaL如今,大型编译器在基本块中的公共代码消除方面做得相当不错,但的确,这是一个相当简单的“手工制作”优化以将不变表达式移动到循环外部。“警告:格式'%d'要求类型为'int',但参数2的类型为'double'(它不显示百分比,而是显示分数)。建议反转/交换最内层代码块中的两行,因为“当前”循环尚未完成,因此不应计算在内。@user3629249我假设在“print”语句之前已经完成了工作,并且“printf”语句本身不是工作本身。这也意味着最终百分比应等于100。@Jongwi是否已修复printf语句以打印整数百分比。不鼓励使用代码回答,您应该解释此代码的工作方式。这将返回错误的结果(例如)当k==0时,则内部循环百分比均未完成,因此不能使用(k+1)。也就是说,在循环完成之前,百分比不应增加。@user3629249我不同意。如果
int iLimit = 10, jLimit = 24, kLimit = 37;
float percentage;
for (int i = 0; i < iLimit; i++) {
for (int j = 0; j < jLimit; j++) {
for (int k = 0; k < kLimit; k++) {
percentage = ((k+1) + j * kLimit + i*jLimit*kLimit)/(float)(iLimit*jLimit*kLimit) * 100;
printf("Percentage Complete = %f\n", percentage);
}
}
}
counter = (k+1) + j * kLimit + i*jLimit*kLimit
100 * percentage / (iLimit * jLimit * kLimit)
printf("Percentage Complete = %d%%\r", (counter*200+iLimit * jLimit * kLimit) /
(2 * iLimit * jLimit * kLimit));