华为2019秋招笔试Java实现(2)

华为2019秋招笔试Java实现(2)

笔试日期2019年8月14日

第二题(200分)

题目描述

某程序员小A,有一种表格数据需要存储在文件中。表格中的每一行,由若干个字段组成,每个字段可以是整数或字符串(字符串只包含数字、字母以及特殊字符!@#%^&*()",)。小A设计了一种存储格式,采用文本的方式对表格数据进行存储。文本文件中的每一行,代表了表格数据中的一行数据。具体格式描述如下:

1、采用逗号分隔不同的字段(逗号前后无空格);

2、数字直接采用10进制的文本存储;

3、字符串的存储规则如下:

​ 1)如果字符串中包含逗号以及双引号,则字符串必须在头尾各增加一个双引号,且中间的双引号需要用连续两个双引号来表示。例如:“a,”“b”,表示字符串a,"b;

​ 2)如果字符串中未包含逗号以及双引号,则字符串不强制要求在头尾各增加一个双引号,可直接存储。例如:abc,或者"abc"都可以;

4、空字符串不存储任何字符,例如:a,b中,有3个字段,分别为a,空字符串,b;

请帮助小A设计一个算法,用来将单行文本,解析成多个字段,并输出。

输入描述

用于存储单行表格数据的一行文本。

输出描述

如果输入字符串格式不正确,则输出结束。

如果字符串格式正确,则输出每个字段的值,每个字段单独占一行。数字采用10进制输出,字符串输出接卸后的值。

空字符串输出–

示例

输入

a,,1,"b,"""

输出

4
a
--
1
b,"

分析

这个解析过程可以认为是括号解析问题的变种,只是处理过程较为复杂,主要涉及以下几个处理。

1、字符串格式验证
观察可以发现,题目中对格式的要求只有第三条的第一小点,也就是双引号的问题。那么怎么判断格式对不对呢?其实不难,按题目要求,双引号的数量必须是偶数,只要统计双引号数量即可。

2、字段数量
这个就是分割的问题,考虑到逗号会出现在字符串中,不能直接统计逗号数量,要统计未被双引号包住的逗号数量。就像括号成对一样,这里的双引号也要成对。那直接拿堆栈来做,在遇到逗号和引号时做判断,其它字符存到临时字符串变量中。

1)逗号

  • 堆栈顶为逗号(或为空),将当前保存的临时字符串存到列表中,删除最后一个引号

  • 堆栈顶为引号,把逗号加到临时字符串尾部

2)引号

  • 堆栈顶为逗号(或为空),把引号压入堆栈
  • 堆栈顶为引号,删除堆栈顶引号,把一个引号加到临时字符串尾部

引号总是成对出现,所以保留第二个引号即可,而一个字段中的头尾引号是作为格式,不出现在字符串中,所以要删除最后一个引号。

3、特殊字符
在处理特殊字符时要记得加上转义符号,不然程序跑不出你期望的结果。

4、空格表示
题目中明确说,空格要转换成–(两个减号),也简单,就是最后输出的时候替换一下就行,或者塞进列表前替换一下。

5、总结
总的来说,这题的考点比较明确,不过作为笔试题过于繁琐,需要考虑的细节很多,会花很多时间,需要比较高的熟练度,也需要从括号解析问题类推。

解答

// 这代码在if条件判断处写的很乱,我也懒得重写,有兴趣的可以按照上述思路自己写一遍
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        sc.close();
        char[] c = s.toCharArray();
        int count = 0;
        for (char cc : c) {
            if (cc == '\"') {
                count++;
            }
        }
        if (count % 2 == 1) {
            System.out.println("ERROR");
            return;
        }
        List<String> list = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        boolean flag = false;
        for (int i = 0; i < c.length; i++) {
            if (c[i] == '\"' && !flag) {
                flag = true;
            }
            if (c[i] == ',' && !flag) {
                String temp = sb.length() == 0 ? "--" : sb.toString();
                list.add(temp);
                sb = new StringBuilder();
            } else if (c[i] == '\"' && flag && (i + 1 == c.length || c[i + 1] == ',')) {
                sb.deleteCharAt(0);
                String temp = sb.length() == 0 ? "--" : sb.toString();
                list.add(temp);
                sb = new StringBuilder();
                i++;
            } else if (c[i] == '\"' && flag && (i + 1 == c.length || c[i + 1] == '\"')) {
                sb.append('\"');
                i++;
            } else {
                sb.append(c[i]);
            }
        }
        System.out.println(list.size());
        for (String ss : list) {
            System.out.println(ss);
        }
    }
}

码字不易,转载请标明出处

你可能感兴趣的:(Java)