欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【每日一题】day13_02 参数解析

程序员文章站 2022-03-15 21:20:04
...

学习目标:

目标:熟练运用Java所学知识


学习内容:

本文内容:使用java解决 参数解析


题目描述

在命令行输入如下命令:

xcopy /s c:\ d:\,

各个参数如下:

参数1:命令字xcopy

参数2:字符串/s

参数3:字符串c:\

参数4: 字符串d:\

请编写一个参数解析程序,实现将命令行各个参数解析出来。

解析规则:

1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” "d:“时,参数仍然是4个,第3个参数应该是字符串C:\program
files,而不是C:\program,注意输出参数时,需要将”"去掉,引号不存在嵌套情况。
3.参数不定长
4.输入由用例保证,不会出现不符合要求的输入

解题思路

建议观看方法二,方法一是我自己做的时候的答案,比较复杂,方法二是我看某位大佬做的结果,清晰明了

  1. 方法一
    使用双指针遍历字符串,当碰到双引号时,继续遍历,直到下一个双引号,将双引号内部的字符串作为一个整体插入到队列中,在引号外面,以空格为分隔符,将两个空格之间的字符串插入到队列中,最后将队列中的元素打印即可
  2. 方法二
    单指针遍历字符串,使用一个标记符 flag=1,当遇见双引号的时候,进行操作 flag^=1,则意味着在双引号内部时flag=0,在双引号外部的时候flag=1,所以当flag=0时,打印所有字符,当flag=1的时候,空格作为换行符打印

实现代码

  1. 方法一
public class Parse {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        split(str);
    }
    public static void split(String str) {
        int start = 0;
        int end = 0;
        int length = str.length();
        Queue<String> queue = new LinkedList<>();//储存解析后的字符串
        while (end < length) {
            //判断字符串最开始是不是双引号
            if (str.charAt(end) == '"') {
                end = end + 1;//从双引号的下一个字符开始
                start = end;
                while (end < length && str.charAt(end) != '"') {
                    //将end遍历到下一个字符串
                    end++;
                }
                queue.offer(str.substring(start, end));//将双引号中的字符串插入队列
                end++;//end指向双引号的下一个位置
                continue;
            }
            //判断字符串中间的双引号,因为每次插入之后,end总指向空格位置
            //所以需要判断end+1位置是不是双引号
            if (str.charAt(end + 1) == '"') {
                end = end + 2;//从双引号的下一个字符开始
                start = end;
                while (end < length && str.charAt(end) != '"') {
                    //将end遍历到下一个字符串
                    end++;
                }
                queue.offer(str.substring(start, end));//将双引号中的字符串插入队列
                end++;//end指向双引号的下一个位置
                continue;
            }
            //将end指向空格之后的字符串,也就是每个解析后字符串开始的位置
            while (end < length && str.charAt(end) == ' ') {
                end++;
            }
            start = end;
            //将end指向解析后字符串结束的位置,也就是空格
            while (end < length && str.charAt(end) != ' ') {
                end++;
            }
            queue.offer(str.substring(start, end));//将两个空格之间的字符串插入队列
        }
        //以下是需要打印的内容
        int size = queue.size();
        System.out.println(size);
        while (!queue.isEmpty()) {
            String s = queue.peek();
            queue.poll();
            System.out.println(s);
        }
    }

}
  1. 方法二
public class Parse {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        split(str);
    }
   public static void split(String str) {
       int count = 0;
       //获取参数的个数
       for (int i = 0; i < str.length(); i++) {
           //遇到双引号需要跳过里面的内容
           if (str.charAt(i) == '"') {
               i++;
               while (str.charAt(i) != '"') {
                   i++;
               }
           }
           if (str.charAt(i) == ' ') {
               count++;
           }
       }
       System.out.println(count + 1);
       int flag = 1;//flag=1表示在双引号外面,flag=0表示在双引号里面
       for (int i = 0; i < str.length(); i++) {
           if (str.charAt(i) == '"') {
               flag ^= 1;
           }
           //1.在双引号外面碰见空格,则换行
           if (str.charAt(i) == ' ' && flag == 1) {
               System.out.println();
           }
           //2.在双引号里面碰见空格则打印空格
           if (str.charAt(i) == ' ' && flag == 0) {
               System.out.print(str.charAt(i));
           }
           //3.不能打印双引号,也不能打印空格,因为空格的所有情况已经包含在了前两种情况
           //  其余的正常打印即可
           if (str.charAt(i) != '"' && str.charAt(i) != ' ') {
               System.out.print(str.charAt(i));
           }
       } 
   }
}