当前位置:Gxlcms > JavaScript > 北京车和家java开发工程师面试题总结

北京车和家java开发工程师面试题总结

时间:2021-07-01 10:21:17 帮助过:8人阅读

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

题目描述:

笔试题: CSV 文件处理

给定一个 CSV 文件,其内容的展现规则如下:

 

- 每一行数据包含多个字段,字段间以 [,] 分割。

- 如果字段值不含有 [,] 和 ["] ,直接解析输出。

- 如果字段值内部含有逗号 [,],在在字段值两边加上双引号 ["] 将字段值括起来。

- 如果字段值内部含有双引号 ["],则字段值两边加上双引号 ["] 括起来,同时,将字段值内的一个双引号 ["] 替换为两个双引号 [""],例如: [下棋,"飞"] 在 CSV 文件中被表现为 ["下棋,""飞"""]。

处理要求:

读入文件 cvs.txt,根据上述 csv 文件的规则进行解析,重新格式化字段生成输出文件 output.txt

第一列转为整形(int)

第二列为字符串型

第三列为字符串型

第四列转为浮点数(float)

第五列转为日期类型(DateTime)

 

输出文件的字段以制表符 [TAB] 来分割字段,

字符串字段输出时用单引号[']括起来

日期字段显示成 YYYY/MM/DD 的格式

 

说明:

1、可以假设字段值只包含单行数据,即字段值本身不含有 [回车换行]

2、不能对文件 csv.txt 作任何修改

 

编程要求:

 

使用任何你熟悉的编程语言编写,时间为 1.5 小时。

题目意思:

这个题目意思描述的不是很清楚,就是给你一个格式化后的csv文件,重新还原到刚开始的文件

还有就是,字段值中同时有 [,] 和 ["] 只会在最外层加一次["]

思路:

1. 主要难点在于第二列和第三列如何区分开,因为第二列和第三列都是字符串

2. 区分的思路为,遍历所有[,],如果[,]左边["]的个数和右边["]的个数都为偶数,则这个[,]为分隔第二个字符串和
第三个字符串的分界点

3. 找到分界点后,格式化输出即可

代码:

package com.st.solution.main;

import com.st.solution.util.DateTimeUtil;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: lilimin
 * @Date: 2019/6/28 20:09
 */
public class Solution {

    public static void main(String[] args) {

        String readFileName = "src/main/resources/csv.txt";
        String writeFileName = "src/main/resources/output.txt";
        readAndWriteFile(readFileName, writeFileName);
    }

    /**
     * 读入文件,格式化
输出 * @param readFileName * @param writeFileName */ public static void readAndWriteFile(String readFileName, String writeFileName) { BufferedReader reader = null; BufferedWriter writer = null; try { reader = new BufferedReader(new FileReader(new File(readFileName))); writer = new BufferedWriter(new FileWriter(new File(writeFileName))); String line = null; while ((line = reader.readLine()) != null) { String formatText = formatText(line); writer.write(formatText); } } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 格式化每一行数据的输出 * @param text * @return */ public static String formatText(String text) { // 如果字段值不含有 [,] 和 ["] ,直接解析输出。 if (!text.contains(",") && !text.contains("\"")) { return text; } String[] splitTextArray = text.split(","); int arrayLength = splitTextArray.length; List<String> tempList = new ArrayList<String>(); tempList.add(splitTextArray[0]); // 如果split后的数组长度为4,说明字符中间没有, if (arrayLength == 4) { tempList.add(formatStrText(splitTextArray[1])); tempList.add(formatStrText(splitTextArray[2])); } else { // 第2列 或者 第3列 字符中间有, // 获取第二列和第三列合起来的字符串 StringBuilder middleText = new StringBuilder(); for (int i = 1; i <arrayLength - 3 ; i++) { middleText.append(splitTextArray[i]).append(","); } middleText.append(splitTextArray[arrayLength- 3]); // 获取第二列和第三列格式化后的字符串 List<String> middleTextList = formatMiddleText(middleText.toString()); tempList.addAll(middleTextList); } tempList.add(splitTextArray[arrayLength - 2]); tempList.add(DateTimeUtil.transferDateformat(splitTextArray[arrayLength - 1])); return String.join(" ", tempList) + "\n"; } /** * 格式化string类型的字符串 * @param text * @return */ public static String formatStrText(String text) { if (text.startsWith("\"") && text.endsWith("\"")) { text = text.substring(1, text.length() - 1); } text = text.replaceAll("\"\"", "\""); return "'" + text + "'"; } /** * 找出第二列和第三列的分界点[,],并且格式化第二列和第三列 * 原则如下,遍历所有[,],如果某个[,] 左边的["]个数和右边的["]个数都为偶数 * 则一定是第二三列的分界点 * @param text * @return */ public static List<String> formatMiddleText(String text) { List<String> list = new ArrayList<String>(); String tempText = text; int index = -1; while ((index = tempText.indexOf(",", index + 1)) != -1) { int leftSum = 0; int rightSum = 0; for (int i = 0; i < index; i++) { if (text.charAt(i) == '"') { leftSum++; } } for (int i = index + 1; i < text.length(); i++) { if (text.charAt(i) == '"') { rightSum++; } } if ((leftSum & 1) == 0 && (rightSum & 1) == 0) { break; } } list.add(formatStrText(text.substring(0, index))); list.add(formatStrText(text.substring(index + 1))); return list; } }
/**
 * @Author: lilimin
 * @Date: 2019/6/28 20:09
 */
public class DateTimeUtil {


    /**
     * 将 yyyy-MM-dd 格式的日期字符串转为 yyyy/MM/dd 格式的日期字符串
     * @param timestr
     * @return
     */
    public static String transferDateformat(String timestr) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("YYYY/MM/DD");
        Date parse = null;
        try {
            parse = sdf1.parse(timestr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sdf2.format(parse);
    }
}

我代码最后的output.txt的内容为

1    'Jane'    '下"棋,"飞"'    56.2    1976/08/236
2    'Kate'    '购物'    49.6    1980/01/25
3    'Jerry'    '羽毛球,爬山'    55.6    1980/05/147

作为一个完整的工程,单测必不可少


/**
 * @Author: lilimin
 * @Date: 2019/6/29 16:14
 */
public class SolutionTest {

    @Test
    public void readAndWriteFile() {
        String readFileName = "src/main/resources/test1csv.txt";
        String writeFileName = "src/main/resources/test1output.txt";

        Solution.readAndWriteFile(readFileName, writeFileName);

        readFileName = "src/main/resources/test2csv.txt";
        writeFileName = "src/main/resources/test2output.txt";

        Solution.readAndWriteFile(readFileName, writeFileName);
    }

    @Test
    public void formatStrText() {
        String text = Solution.formatStrText("\"\"\"text\"\"\"");
        assertEquals("'\"text\"'", text);
    }

    @Test
    public void formatMiddleText() {
        List<String> textList = Solution.formatMiddleText("str1,str2");
        assertEquals("'str1'", textList.get(0));
        assertEquals("'str2'", textList.get(1));

        textList = Solution.formatMiddleText("\"str1\",\"str2\"");
        assertEquals("'str1'", textList.get(0));
        assertEquals("'str2'", textList.get(1));

        textList = Solution.formatMiddleText("\"\"\"str1\",\"str2\"");
        assertEquals("'\"str1'", textList.get(0));
        assertEquals("'str2'", textList.get(1));
    }
}

单测的输入和输出如下

test1.csv

2,",Kate",购物,49.6,1979-12-56
3,Jerry,"羽毛球,爬山",55.6,1980-5-26

test1output.txt

2    ',Kate'    '购物'    49.6    1980/01/25
3    'Jerry'    '羽毛球,爬山'    55.6    1980/05/147

test2.csv

1,Jane,"下""棋,""飞""",56.2,1976-8-23
2,"Kate,Kate","购物,购物",49.6,1979-12-56
3,Jerry,"羽毛球,爬山",55.6,1980-5-26

test2output.txt

1    'Jane'    '下"棋,"飞"'    56.2    1976/08/236
2    'Kate,Kate'    '购物,购物'    49.6    1980/01/25
3    'Jerry'    '羽毛球,爬山'    55.6    1980/05/147

推荐

人气教程排行