【问题标题】:How do I output to the console in a specific layout?如何以特定布局输出到控制台?
【发布时间】:2017-01-05 13:35:58
【问题描述】:

我正在做一个小项目,该项目在一行上接受用户输入(匹配结果),拆分输入并以不同格式输出相同的数据。我正在努力寻找一种以特定格式输出数据的方法。除了玩的总游戏数之外,我希望我的程序生成一个类似于输出格式的图表

home_name [home_score] | away_name [away_score]

这是我目前拥有的代码,它允许用户按以下格式逐行输入结果

home_name : away_name : home_score : away_score

直到他们进入停止,这会打破循环(并希望很快输出数据)。

import java.util.*;
public class results {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int totalGames = 0;
        String input = null;
        System.out.println("Please enter results in the following format"
                + " home_name : away_name : home_score : away_score"
                + ", or enter stop to quit");

        while (null != (input = scan.nextLine())){
            if ("stop".equals(input)){
                break;
            }
            String results[] = input.split(" : ");
            for (int x = 0; x < results.length; x++) {

            }       
        totalGames++;
        }
        System.out.println("Total games played is " + totalGames);  
    }
}

【问题讨论】:

  • 顺便说一句,Yoda conditions 您的 while 循环使用。有什么理由吗?
  • 没有具体原因,可能只是我接受的教学风格。 while ((input = scan.nextLine()) != "stop") 似乎简化了事情。
  • 不要使用==!= 运算符比较字符串。您需要改用equals。例如,while ((input = ...) != null &amp;&amp; !input.equals("stop"))

标签: java


【解决方案1】:

你可以看到here

您可以根据需要设置文本格式。

一般语法是 %[arg_index$][flags][width][.precision]conversion char  参数 编号从 1(不是 0)开始。所以要打印第一个参数,你 应该使用 1$(如果您使用显式排序)。

【讨论】:

    【解决方案2】:

    您可以使用正则表达式来解析该行:

    (\w)\s(\w)\s|\s(\w)\s(\w)

    基于来自(来自http://tutorials.jenkov.com/java-regex/matcher.html)的 Java 代码

    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    
        public class MatcherFindStartEndExample{
    
            public static void main(String[] args){
    
                String text = "Belenenses 6 | Benfica 0";
    
                String patternString = "(\\w+)\\s(\\w+)\\s\\|\\s(\\w+)\\s(\\w+)";
    
                Pattern pattern = Pattern.compile(patternString);
                Matcher matcher = pattern.matcher(text);
    
    
                while (matcher.find()){
                        System.out.println("found: " + matcher.group(1));
                        System.out.println("found: " + matcher.group(2));
                        System.out.println("found: " + matcher.group(3));
                        System.out.println("found: " + matcher.group(4));
                }
            }}
    

    使用此代码代替您的

     String results[] = input.split(" : ");
                for (int x = 0; x < results.length; x++) {
    
                }
    

    【讨论】:

      【解决方案3】:

      你应该分两次做事:

      1) 检索用户输入的信息并将其存储在自定义类的实例中:PlayerResult

      2) 根据预期的格式执行输出。您还应该在创建图形表之前计算每列的最大大小。
      否则你可能会得到一个丑陋的渲染。

      第一步:

      List<PlayerResult> playerResults = new ArrayList<PlayerResult>();
      
      ...
      String[4] results = input.split(" : "); 
      playerResults.add(new PlayerResult(results[0],results[1],results[2],results[3])
      

      第二步:

      // compute length of column
      int[] lengthByColumn = computeLengthByColumn(results);
      int lengthHomeColumn = lengthByColumn[0];
      int lengthAwayColumn = lengthByColumn[1];
      
      // render header
      System.out.print(adjustLength("home_name [home_score]", lengthHomeColumn));
      System.out.println(adjustLength("away_name [away_score]", lengthAwayColumn));
      
      // render data
      for (PlayerResult playerResult : playerResults){
         System.out.print(adjustLength(playerResult.getHomeName() + "[" + playerResult.getHomeName() + "]", lengthHomeColumn));
         System.out.println(adjustLength(playerResult.getAwayName() + "[" + playerResult.getAwayScore() + "]", lengthAwayColumn));
       }
      

      【讨论】:

        【解决方案4】:

        您可以通过将results 数组值添加到finalResults ArrayList 来保留游戏统计信息。然后将其结果输出为输入stop
        对于计算每个团队的总结果,HashMap&lt;String, Integer&gt; 是最佳选择。

        为了清楚起见,这里是带有 cmets 的完整代码:

        import java.util.*;
        
        // following the naming conventions class name must start with a capital letter
        public class Results {
            public static void main(String[] args) {
                Scanner scan = new Scanner(System.in);
                int totalGames = 0;
                String input;
                System.out.println("Please enter results in the following format: \n"
                        + "'HOME_NAME : AWAY_NAME : HOME_SCORE : AWAY_SCORE' \n"
                        + "or enter 'stop' to quit");
        
                // HashMap to keep team name as a key and its total score as value
                Map<String, Integer> scoreMap = new HashMap<>();
                // ArrayList for storing game history
                List<String> finalResults = new ArrayList<>();
                // don't compare null to value. Read more http://stackoverflow.com/questions/6883646/obj-null-vs-null-obj
                while ((input = scan.nextLine()) != null) {
                    if (input.equalsIgnoreCase("stop")) {   // 'Stop', 'STOP' and 'stop' are all OK
                        scan.close(); // close Scanner object
                        break;
                    }
                    String[] results = input.split(" : ");
        
                    // add result as String.format. Read more https://examples.javacodegeeks.com/core-java/lang/string/java-string-format-example/
                    finalResults.add(String.format("%s [%s] | %s [%s]", results[0], results[2], results[1], results[3]));
        
                    // check if the map already contains the team
                    // results[0] and results[1] are team names, results[2] and results[3] are their scores
                    for (int i = 0; i < 2; i++) {
                        // here is used the Ternary operator. Read more http://alvinalexander.com/java/edu/pj/pj010018
                        scoreMap.put(results[i], !scoreMap.containsKey(results[i]) ?
                                Integer.valueOf(results[i + 2]) :
                                Integer.valueOf(scoreMap.get(results[i]) + Integer.valueOf(results[i + 2])));
                    }
                    totalGames++; // increment totalGames
                }
        
                System.out.printf("%nTotal games played: %d.%n", totalGames); // output the total played games
        
                // output the games statistics from ArrayList finalResults
                for (String finalResult : finalResults) {
                    System.out.println(finalResult);
                }
        
                // output the score table from HashMap scoreMap
                System.out.println("\nScore table:");
                for (Map.Entry<String, Integer> score : scoreMap.entrySet()) {
                    System.out.println(score.getKey() + " : " + score.getValue());
                }
            }
        }
        

        现在测试输入:

        team1 : team2 : 1 : 0
        team3 : team1 : 3 : 2
        team3 : team2 : 2 : 2
        sToP
        

        输出是:

        Total games played: 3.
        
        team1 [1] | team2 [0]
        team3 [3] | team1 [2]
        team3 [2] | team2 [2]
        
        Score table:
        team3 : 5
        team1 : 3
        team2 : 2
        

        【讨论】:

        • 是的,格式是完美的!但是,我正在努力弄清楚如何在循环中断后以该格式输出所有结果,例如假设用户输入了 3 行结果,然后停止。这打破了循环,只有这样我才会希望数据以这种格式相互输出
        • 说到这个话题,你有没有机会帮我解决另一个问题?除了显示总比赛数之外,我还想记录总得分和总得分,我该怎么做呢?
        • HashMap&lt;String, Integer&gt; 是您这里最好的朋友。寻找我的答案,我完全更新了它。顺便说一句,如果你想按字母顺序输出团队,你可以使用TreeMapLinkedHashMap 如果你想保持看跌顺序。希望对您有所帮助。
        猜你喜欢
        • 2021-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        • 1970-01-01
        • 1970-01-01
        • 2013-11-14
        • 1970-01-01
        相关资源
        最近更新 更多