Java do while循环仅在条件使用“时工作”;及;不是";或;
我有一个使用以下条件的do-while循环:Java do while循环仅在条件使用“时工作”;及;不是";或;,java,do-while,boolean-expression,Java,Do While,Boolean Expression,我有一个使用以下条件的do-while循环:while(p!=0&&k!=0)。当我使用&&作为操作符时,循环工作正常。但是,出于程序的目的,我需要使用|。循环运行一次,然后挂起,不会引发任何异常。有人能告诉我为什么do while循环挂起吗?带注释的完整代码: //Import necessary dependencies import java.util.*; import javax.swing.JFrame; import org.math.plot.*; public class f
while(p!=0&&k!=0)代码>。当我使用&&
作为操作符时,循环工作正常。但是,出于程序的目的,我需要使用|
。循环运行一次,然后挂起,不会引发任何异常。有人能告诉我为什么do while循环挂起吗?带注释的完整代码:
//Import necessary dependencies
import java.util.*;
import javax.swing.JFrame;
import org.math.plot.*;
public class fixedSimulation
{
//Initialize variables
public static int pacifists, killers, deaths, survivals, csvIndex = 0;
public static double[] csvProb = new double[121];
public static int[] csvParamP = new int[121], csvParamK = new int[121];
public static void main(String[] args)
{
//These "for" loops serve to run the simulation 100 times for every possible combination of 0-10 pacifists and 0-10 killers
for(int p = 0; p<11; p++)
{
pacifists = p;
for(int k = 0 ;k<11; k++)
{
killers = k;
//Display the number of pacifists and killers in current group (100 trials) of simulations
System.out.println("P" + p + "K" + k);
deaths = 0; survivals = 0;
for(int t=0; t<100; t++)
{
//Run simulation
doRun();
//Display current total of deaths and survivals for simulation group
System.out.println("\nDeaths=" + deaths + " Survivals=" + survivals);
//Display current probability for simulation group
System.out.println("Probability of survival = " + (((double)survivals/(double)(survivals+deaths))*100) + "%\n");
}
//Record data for later use
csvProb[csvIndex] = (((double)survivals/(double)(survivals+deaths))*100);
csvParamP[csvIndex] = p;
csvParamK[csvIndex] = k;
csvIndex++;
}
}
//Display collected data in "Comma-separated value" format, for easy use in spreadsheet applications
System.out.print("CSV Data:\nPacifists,Killers,Probability");
for(int x = 0; x < 121; x++)
{
System.out.print("\n" + csvParamP[x] + "," + csvParamK[x] + "," + csvProb[x]);
}
//Prepare to display scatter plot
System.out.println("\nPlotting");
//Create arrays for plot data
double[] plotX = new double[121], plotY = new double[121], plotZ = new double[121];
//Populate arrays
for(int x = 0; x < 121; x++)
{
plotX[x] = csvParamP[x];
plotY[x] = csvParamK[x];
plotZ[x] = csvProb[x];
}
//Initialize plotting panel
Plot3DPanel plotPanel = new Plot3DPanel();
plotPanel.addScatterPlot("Plot", plotX, plotY, plotZ);
plotPanel.setAxisLabels("Pacifists", "Killers", "Probability of Survival");
System.out.println("Plot Done, opening frame");
//Create UI window
JFrame plotFrame = new JFrame("Pacifists and Killers");
plotFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
plotFrame.setSize(700, 700);
plotFrame.setContentPane(plotPanel);
plotFrame.setVisible(true);
System.out.println("Frame opened");
}
//Simulation method
public static void doRun()
{
//Instantiate values for test
int p=pacifists, k=killers;
//"do" loop simulates meeting, checks to see if there are still killers and pacifists to meet, and if so simulates subsequent meetings
do
{
Random r = new Random();
//Pick two numbers between 0 and 2; random result of 0 is pacifist, 1 is killer. 2 is used as upper limit because random limit is exclusive.
int r1 = r.nextInt(2), r2 = r.nextInt(2);
//Check to see if 2 pacifists have met (if first number [r1] is 0 and second number [r2] is 0)
if( (r1==0 && r2==0) && (p>=2) /* Check to see if there are 2+ pacifists; must be 2+ pacifists for them to meet */ )
{
//Display meeting and result
System.out.println("P&P: P=" + p + " K=" + k);
}
//Check to see if a pacifist and killer have met (if first number [r1] is 0 and second number [r2] is 1)
else if( ((r1==0 && r2==1) || (r1==1 && r2==0)) && (p>=1 && k>=1) /* Check to see if there are 1+ pacifist(s) and 1+ killer(s); must be 1+ pacifist(s) and 1+ killer(s) for them to meet */)
{
//Remove pacifist
p--;
//Display meeting and result
System.out.println("P&K: P=" + p + " K=" + k);
}
//Check to see if 2 killers have met (if first number [r1] is 1 and second number [r2] is 1)
else if( (r1==1 && r2==1) && (k>=2) /* Check to see if there are 2+ killers; Must be 2+ killers for them to meet */ )
{
//Remove 2 killers
k-=2;
//Display meeting and result
System.out.println("K&K: P=" + p + " K=" + k);
}
}
//Check to see that pacifists and killers still exist
------> while(p!=0 || k!=0); <------
//Display and record final result
if(k==0)
{
System.out.println("Traveler survives");
survivals++;
}
else if(k!=0)
{
System.out.println("Traveler dies");
deaths++;
}
//Catch extraneous errors
else System.out.println("ERROR: Unknown end");
}
}
//导入必要的依赖项
导入java.util.*;
导入javax.swing.JFrame;
导入org.math.plot.*;
公共类固定模拟
{
//初始化变量
公共静态int和平主义者、杀手、死亡、幸存者,csvIndex=0;
公共静态双精度[]csvProb=新双精度[121];
公共静态int[]csvParamP=new int[121],csvParamK=new int[121];
公共静态void main(字符串[]args)
{
//这些“for”循环用于对0-10个和平主义者和0-10个杀手的每种可能组合运行100次模拟
对于(int p=0;p=1)/*检查是否有1+和平主义者和1+杀手;必须有1+和平主义者和1+杀手才能满足*/)
{
//罢免和平主义者
p--;
//显示会议和结果
系统输出打印项次(“P&K:P=“+P+”K=“+K”);
}
//检查两个杀手是否相遇(如果第一个数字[r1]为1,第二个数字[r2]为1)
否则如果((r1==1&&r2==1)&&(k>=2)/*检查是否有2个以上的杀手;必须有2个以上的杀手才能满足*/)
{
//移除2个杀手
k-=2;
//显示会议和结果
系统输出打印项次(“K&K:P=“+P+”K=“+K”);
}
}
//看看和平主义者和杀手是否依然存在
------>而(p!=0 | | k!=0);来更正@anonymous之前的评论
p!=0 && k!=0 is equal to !(p == 0 || k == 0)
使用此代码时(p!=0 | | k!=0)
(如中所述),使用会出现一些问题
当k
为1时(在第一次调用doRun
时,它开始时为),您创建了一个无限循环,因为您需要k>=2
来进入其递减的块:
else if( (r1==1 && r2==1) && (k>=2) /* Check to see if there are 2+ killers; Must be 2+ killers for them to meet */ )
{
//Remove 2 killers
k-=2;
//Display meeting and result
System.out.println("K&K: P=" + p + " K=" + k);
}
因此,k
将永远不会减少,p!=0 | | k!=0
将始终为真
有一些方法可以解决这个问题,这将揭示一个相关的问题。如果k
开始时是奇数,它永远不会是零。它将从1
跳到-1
,但您正在用0
检查不等式,而不是使用
在更基本的层面上,为什么要运行循环,直到p
和k
都为零?在您的场景中,这样做似乎是错误的
完全分开,不需要在循环中不断创建新的随机对象。创建一次,然后重复调用nextInt
。因此,请注意几点
正如其他人所评论和回答的那样,DeMorgan定律展示了将逻辑语句从使用and转换为使用OR的正确方法。正如您所发现的,仅仅用and替换and或将导致无休止的问题。将来我建议使用调试器(可能在Eclipse中?)逐步检查您的逻辑,并查看它是如何解决的
但是,更一般地说,像这样的逻辑陈述是没有魔力的。证明DeMorgan作品的最简单方法是建立一个逻辑表:
| Expression 1 || | Expression 2
p!=0 | k!=0 | (p!=0 && k!=0) || p==0 | k==0 | (p==0 || k==0) | !(p==0 || k==0)
------+------+----------------++------+------+----------------+-----------------
true | true | true ||false |false | false | true
true |false | false ||false | true | true | false
false | true | false || true |false | true | false
false |false | false || true | true | true | false
这些类型的表很容易绘制,我希望也很容易理解。您可以看到左侧的“表达式1”与右侧的“表达式2”是如何等效的。如果您的逻辑变得更复杂,表可能会变大,但这种谨慎的推导将防止最常见的错误。p!=0&&k!=0等于!(p==0 | k==0)将来,请发布一个。我们不需要所有与问题无关的不必要的代码。@SotiriosDelimanolis我正在使用while(p!=0 | | k!=0)
因为我在编写程序后意识到它需要做其他事情。@ZongZhengLi抱歉,我不知道是什么导致了问题,所以我认为拥有所有的代码会有所帮助。减少代码的过程通常会使错误所在的位置变得明显。代码越短,其他人也越容易理解(因此,为了帮助您)。除了李宗正的建议外,您还应该大致显示您遇到问题的代码(因此,这里您将使用|
公式)、输出/错误是什么,以及期望或希望它是什么(如果不明显)。这应该是一个评论,而不是一个答案。哦,等等……是的!@DavidWallace为什么它不是一个答案?@DavidWallace我只是在想同样的事情。请教育我。也许是为了OP的利益。展示它是如何产生的。我已经重新阅读了这个问题。里面实际上没有问题。所以不可能回答。所以我取消了我的反对票这里是rom,并将一个应用于问题。这个答案可能与它得到的一样好。谢谢,我将移动随机对象并查看其他点!