问题描述
在输入权重和利润上陷入无限循环,无论您输入多少输出都不会向前推进 任何帮助,将不胜感激 下面是代码
import java.util.*;
import java.text.*;
class fracknapsack
{
public static void main(String args[])
{
Scanner sc = new Scanner(system.in);
DecimalFormat df = new DecimalFormat("##.##");
System.out.println("Enter number of elements: ");
int n = sc.nextInt();
System.out.println("Enter total mass: ");
float m = sc.nextFloat();
System.out.println("Enter weight and profit of "+n+" elements: ");
float w[] = new float[n];
float p[] = new float[n];
float r[] = new float[n];
float f[] = new float[n];
float max = (float)0;
int flag = 0;
//for(int i=0; i<n; i++)
//{
// int a = sc.nextInt();
// w[i] = (float)a;
//}
//for(int i=0; i<n; i++)
//{
// int b = sc.nextInt();
// p[i] = (float)b;
//}
for(int i=0; i<=n; i++)
{
int a = sc.nextInt();
int b = sc.nextInt();
w[i] = (float)a;
p[i] = (float)b;
r[i] = p[i]/w[i];
f[i] = (float)0;
if(p[i]>max)
{
max = p[i];
flag = i;
}
}
float tprofit = (float)0;
while(m>0)
{
if(m>max)
{
tprofit = tprofit + p[flag];
f[flag] = (float)1;
m = m - max;
}
else
{
float fraction = max/m;
tprofit = tprofit + p[flag]*fraction;
f[flag] = fraction;
max = 0;
}
float j = (float)0;
for(int i=0; i<n; i++)
{
if(j>r[i] && j<max)
{
j = r[i];
flag = i;
}
}
max = j;
}
System.out.println();
System.out.println();
System.out.println("Fraction of weights included: ");
System.out.println("Weights \t|\t Fraction");
for(int i=0; i<n; i++)
{
System.out.println(df.format(w[i])+"\t|\t"+df.format(f[i]));
}
System.out.println();
System.out.println("Total Profit = "+df.format(tprofit));
}}
我相信这应该可以正常运行,但不是。 很困惑可能是什么问题。 包含另一个用于测试的 for 循环,问题仍然存在。
解决方法
在第 32 行(第一个循环)中,您过于频繁地迭代一个条目。 您想填充数组中的所有 n 个条目 - 但是当从 i=0 迭代到 i 时,您正在填充 n+1
所以当我尝试你的代码时,我得到一个 ArrayIndexOutOfBoundsException。
我解决了这个问题,但导致无限循环,因为“max”变量始终保持为 0,而 m 永远不会改变(始终保持更大的 0)。
作为一般提示,您应该使用更多的名称来命名变量并注释代码。
,如前所述,for 循环应该运行到 i < n
而不是 i <= n
这是您的代码注释以突出问题。您永远不会输入if(j>r[i] && j<max)
:
while(m>0)
{
if(m>max)
{
tprofit = tprofit + p[flag];
f[flag] = (float)1;
m = m - max;
}
else
{
float fraction = max/m;
tprofit = tprofit + p[flag]*fraction;
f[flag] = fraction;
max = 0; // issue: setting max == 0
}
float j = (float)0; // issue: setting j == 0 therefore line 66 is never true
for(int i=0; i<n; i++)
{
if(j>r[i] && j<max) // issue: j=0 and max=0 therefore j < max == false
{ // issue: also,can r[i] be negative? That would mean a negative profit or mass therefore it is always the case that j>r[i] == false
j = r[i];
flag = i;
}
}
max = j; // we never entered the if statement so j==0. We will never enter the if statement on line 50 and we will now loop infinitely
}
我(也)建议使用更长、更具描述性的变量名称。我不知道你在做什么,我不想花时间从逻辑上推理出来,所以我无法修复你损坏的 if
语句逻辑,但至少我可以指出你发现事情正在破裂。
更长、更多的描述变量名称将使您作为编码员的生活更轻松。每个人都说你应该很好地注释你的代码,但我认为这是错误的。我相信你的变量名应该清楚你的代码在做什么,你应该只需要注释非常复杂的代码部分。我推荐观看Uncle Bob's Clean Code on YouTube。它教会了我很多关于编写更好代码的知识。这使得回去重新阅读我自己的作品变得更加容易。