【问题标题】:How do I restart a do-while loop if the last condition fails?如果最后一个条件失败,如何重新启动 do-while 循环?
【发布时间】:2017-07-04 16:21:07
【问题描述】:

我自己试过这个,到处寻找答案,似乎找不到合适的解决方法。我之前在这个网站上找到了很多答案,所以我注册问我的问题。我有一个程序可以循环 6 个用户并将他们分配到一个位置。用户:Alpha、bravo、charlie、delta、echo 和 frank。位置:1,2,3,4,5,6。我正在生成随机数以将用户分配到他们的位置。我有一条要检查的规则;任何用户都不能被分配到同一个位置两次。由于此规则以及用户对站点的随机分配,有时位置 6 的唯一用户是在先前轮换中已被分配到位置 6 的用户。当这种情况发生时,我的程序崩溃了,这是理所当然的。我该如何克服呢?我有一些程序会做出正确选择的例子,我有 6 次成功的轮换。我希望每次都有 6 次成功的轮换。我花了两周时间试图弄清楚这一点。我能得到的任何帮助将不胜感激。谢谢你。我在下面粘贴了我的代码。我正在使用 Java。

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.CardLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;


public class test extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    test frame = new test();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */



    //TODO  
    int randnum[] = new int [7];
    int numOfRotations = 1;
    String[] String_CurrentOperator = new String[7];
    Random rand_opers = new Random();

    List<Integer> ArrayList_UsedRandNums = new ArrayList<>();
    List<List<String>> ArrayList_MainOperatorHistory = new ArrayList<List<String>>();
    List<String> ArrayList_AllOpers = new ArrayList<>();
    List<String> ArrayList_UsedOpers = new ArrayList<>();
    List<String> ArrayList_OperatorHistory1 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory2 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory3 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory4 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory5 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory6 = new ArrayList<>(); 


    public test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBackground(Color.DARK_GRAY);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new CardLayout(0, 0));

        JButton btnShuffle = new JButton("SHUFFLE");
        contentPane.add(btnShuffle, "name_253561263644851");
        btnShuffle.addActionListener(this);

        ArrayList_AllOpers.add("POSITION ZERO");
        ArrayList_AllOpers.add("Alpha");
        ArrayList_AllOpers.add("Bravo");
        ArrayList_AllOpers.add("Charlie");
        ArrayList_AllOpers.add("Delta");
        ArrayList_AllOpers.add("Echo");
        ArrayList_AllOpers.add("Frank");

        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory2);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory3);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory4);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory5);
        ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory6);
    }


    public void actionPerformed(ActionEvent arg0) {

        /*******************************
         *****ASSIGN ALL OPERATORS******
         *******************************/
        System.out.println("THIS IS ROTATION "+numOfRotations);
        genRandoms();

        for(int i=1; i<6+1; i++){
            do{
                //randnum[i] = rand_opers.nextInt(6)+1;
                String_CurrentOperator[i] = ArrayList_AllOpers.get(randnum[i]);
            }
            while(ArrayList_UsedOpers.contains(String_CurrentOperator[i]) || ArrayList_MainOperatorHistory.get(i).contains(String_CurrentOperator[i]));

            ArrayList_UsedOpers.add(String_CurrentOperator[i]); //add to used names thus far
        }


        for(int i=1; i<6+1; i++){
            System.out.println(String_CurrentOperator[i]);                       //Prints the name of the operator working on the station               
            ArrayList_MainOperatorHistory.get(i).add(String_CurrentOperator[i]); //adds operator to list of all users who have been assigned to this station
        }

        //Perform cleanup actions for next iteration of the loop
        numOfRotations++;               //increment the rotation count by 1
        ArrayList_UsedRandNums.clear(); //clear the list of randum numbers used
        ArrayList_UsedOpers.clear();    //clear the list of assigned operators
        System.out.println("");
    }   


    public void genRandoms(){
        for(int i=1; i<6+1; i++){
            do{
                randnum[i] = rand_opers.nextInt(6)+1;
            }
            while (ArrayList_UsedRandNums.contains(randnum[i]));

            ArrayList_UsedRandNums.add(randnum[i]);   //add randnum[i] to list of random numbers used thus far
        }
    }
}

【问题讨论】:

  • shuffleCollections 中有两个变体。你能用那个吗? docs.oracle.com/javase/6/docs/api/java/util/Collections.html
  • 什么是ArrayList_AllOpers.add("POSITION ZERO");?看起来您正试图避免数组从零开始的性质。不要,你需要接受它。
  • 哇,所有这些回复都已经很棒了!惊人的。我会查看并尝试它们并报告回来。非常感谢!韦斯顿你是对的。这次我故意尽量避免零基础的性质。不过,我倾向于更频繁地接受它。

标签: java loops random do-while


【解决方案1】:

问题可以重新表述如下:

您有一个 6x6 网格/矩阵:

   1 2 3 4 5 6
r1 A B C D E F
r2 F A B C D E
r3 E F A B C D
r4 D E F A B C
r5 C D E F A B
r6 B C D E F A

列是座位位置,行是旋转,单元格值是 Alpha、Beta、Charlie... 您希望随机打乱此网格,而不会违反每行和每列中的值仅出现一次的约束。

这类似于随机播放数独网格。

这个任务不是太简单。这是一个使用回溯提供解决方案的答案:How to Generate a -complete- sudoku board

一个简单的解决方案是随机交换初始网格的行和列。

这是我对具有回溯功能的希望没有错误的解决方案的尝试: 最初使用 Fisher-Yates 算法对行进行洗牌。然后使用回溯自上而下验证网格。

public static int[][] fillGrid(Random random, int size){
    int[][] grid = new int[size][size];

    do{
        for(int row = 0; row < size; row++){
            grid[row] = IntStream.rangeClosed(1, size).toArray();
            shuffleArray(grid[row], random); //randomize row                
        }
    }while(!validate(grid, 0, 0)); //defensive: reroll if failed to validate (should not happen)

    return grid;
}

private static boolean validate(int[][] grid, int row, int col){        
    if(col == grid.length){     
        if(row == grid.length-1){
            //end of grid reached -> whole grid is valid
            return true;
        }
        //end of valid row reached -> validate next row         
        return validate(grid, row + 1, 0);
    }       
    //search for a value that makes the whole row valid
    for(int i = col; i < grid.length; i++){
        swap(grid[row], i, col); //try next value

        //check if the current column is valid
        boolean validCol = true;
        for(int j = 0; j < row; j++){
            if(grid[j][col] == grid[row][col]){
                validCol = false;
                break;
            }
        }

        if (validCol && validate(grid, row, col + 1)){
            //the whole row is valid
            return true;
        }   
        swap(grid[row], i, col); //value does not fit -> swap back
    }   
    //the row is invalid        
    return false;
}

private static void shuffleArray(int[] array, Random random){
    for (int i1 = array.length - 1; i1 > 0; i1--){
      int i2 = random.nextInt(i1 + 1);
      swap(array, i1, i2);
    }
}

private static void swap(int[] array, int i1, int i2){
    int temp = array[i1];
    array[i1] = array[i2];
    array[i2] = temp;
}

方法调用fillGrid(new Random(), 6) 将为您提供一个满足约束的打乱网格。您可以在 for 循环内的每次迭代中使用 [numOfRotations-1][i-1] 访问这些值。不需要使用 ArrayList_UsedOpersArrayList_MainOperatorHistory

【讨论】:

  • 我喜欢它,但为什么简单的解决方案质量低?
  • @weston 在数独上应用交换方法会导致网格的随机性很差。然而,这似乎只是这种情况,因为 3x3 盒子有额外的限制。因此,对于这种更简单的问题,它确实可能是一个很好的解决方案。目前,我尝试使用回溯。
  • 哇计算器!感谢您的辛勤工作,这看起来像是我必须使用的解决方案,我希望我只是看不到解决方案,并希望它只是修复几行代码,但在这种情况下回溯是最好的方法。再次感谢您的帖子。
【解决方案2】:

我认为你的逻辑似乎是正确的。但是,数组是从零开始的,所以这就是您遇到问题的原因。尝试像这样更改两个 for 循环:

for(int i=0; i<6; i++){

【讨论】:

    【解决方案3】:

    到目前为止,我提出了这个每次都有效的解决方案。感谢您的所有反馈。它可能不是最有效的代码,但肯定可以按预期工作。我进行了一些调整,以允许计算最多 10 次旋转。不过,它真的很挣扎。希望有人能发现这很有用。

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import java.awt.Color;
    import java.awt.CardLayout;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import javax.swing.JButton;
    
    
    public class test extends JFrame implements ActionListener {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private JPanel contentPane;
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        test frame = new test();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
    
    
    
        //TODO  
        int numOfStations = 6;
        boolean cleared[] = new boolean[21];
        boolean finalCleared = false;
        int randnum[] = new int [numOfStations+1];
        int numOfRotations = 1;
        String[] String_CurrentOperator = new String[numOfStations+1];
        Random rand_opers = new Random();
    
        List<Integer> ArrayList_UsedRandNums = new ArrayList<>();
        List<List<String>> ArrayList_MainOperatorHistory = new ArrayList<List<String>>();
        List<String> ArrayList_AllOpers = new ArrayList<>();
        List<String> ArrayList_CurrentRotationOperators = new ArrayList<>();
        List<String> ArrayList_UsedOpers = new ArrayList<>();
        List<String> ArrayList_OperatorHistory1 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory2 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory3 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory4 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory5 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory6 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory7 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory8 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory9 = new ArrayList<>(); 
        List<String> ArrayList_OperatorHistory10 = new ArrayList<>(); 
    
    
        public test() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 300);
            contentPane = new JPanel();
            contentPane.setBackground(Color.DARK_GRAY);
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(new CardLayout(0, 0));
    
            JButton btnShuffle = new JButton("SHUFFLE");
            contentPane.add(btnShuffle, "name_253561263644851");
            btnShuffle.addActionListener(this);
    
            ArrayList_AllOpers.add("POSITION ZERO");
            ArrayList_AllOpers.add("A");
            ArrayList_AllOpers.add("B");
            ArrayList_AllOpers.add("C");
            ArrayList_AllOpers.add("D");
            ArrayList_AllOpers.add("E");
            ArrayList_AllOpers.add("F");
            ArrayList_AllOpers.add("Greek");
            ArrayList_AllOpers.add("Hospital");
            ArrayList_AllOpers.add("Indigo");
            ArrayList_AllOpers.add("Juliette");
    
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory2);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory3);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory4);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory5);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory6);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory7);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory8);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory9);
            ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory10);
        }
    
    
        public void actionPerformed(ActionEvent arg0) {
            finalCleared = false;
            for(int j=1; j<numOfStations+1; j++){       
                cleared[j]=false;           
            }
    
            for(int j=numOfStations+1; j<21; j++){  
                cleared[j]=true;            
            }
    
            /*******************************
             *****ASSIGN ALL OPERATORS******
             *******************************/
            //System.out.println("THIS IS ROTATION "+numOfRotations);
    
            for(int i=1; i<1+1; i++){
                do{
                    //clears the list of operators used during last rotation                
                    ArrayList_CurrentRotationOperators.clear();
    
                    //Assign the operators
                    for(int j=1; j<numOfStations+1; j++){       
                        String_CurrentOperator[j] = ArrayList_AllOpers.get(randnum[j]);     
                    }
    
                    //1. Ensure assigned operators or unique else fail finalCleared check
                    //2. If finalCleared is true then exit do and for loops
                    for(int j=1; j<numOfStations+1; j++){       
                        if (ArrayList_MainOperatorHistory.get(j).contains(String_CurrentOperator[j]) || ArrayList_CurrentRotationOperators.contains(String_CurrentOperator[j])){
                            cleared[j]=false;
                        }
                        else{
                            cleared[j]=true;
                            ArrayList_CurrentRotationOperators.add(String_CurrentOperator[j]);
                        }           
                    }
    
    
                    if (cleared[1]==true && cleared[2]==true && cleared[3]==true && cleared[4]==true && cleared[5]==true && cleared[6]==true 
                            && cleared[7]==true && cleared[8]==true && cleared[9]==true && cleared[10]==true){
                        finalCleared=true;
                    }
                    else{
                        genRandoms();
                    }
                }
                while(finalCleared == false);
            }
    
            //1. Prints the name of the operator working on the station
            //2.  Adds operator to list of all users who have been assigned to station
            for(int i=1; i<numOfStations+1; i++){
                System.out.print(String_CurrentOperator[i]+" ");                                      
                ArrayList_MainOperatorHistory.get(i).add(String_CurrentOperator[i]);
            }
    
            //Perform cleanup actions for next iteration of the loop
            //1.  increment the rotation count by 1
            numOfRotations++;              
            System.out.println("");
        }   
    
    
    
        /*********************
         **genRandoms Method**
         *********************/
        public void genRandoms(){
            for(int i=1; i<numOfStations+1; i++){
                randnum[i] = rand_opers.nextInt(numOfStations)+1;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-26
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多