Java 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

我有一个使用以下条件的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 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,并将一个应用于问题。这个答案可能与它得到的一样好。谢谢,我将移动随机对象并查看其他点!