动物的坐标数据

只愿长相守 提交于 2020-02-25 16:03:20

题目描述

动物学家研究动物群体行为的一种方式是将信号发射器安装到动物的身上,然后追踪动物在一定区域内的活动路线。科学家不但希望了解动物的活动路线,而且希望了解任意一个指定的时间上所有动物的分部。

假设现在有多个动物在指定的区域内活动。为了节省存储空间,科学家并没有选择存储每一个时刻的动物分布快照,而是存储当前时刻与上一个时刻的变化。假设每一个动物的位置由 x , y 两个坐标确定 (为了简单起见,我们假设所有坐标和坐标的变化均为整数),则我们规定一下的存储格式:

1、第一行是一个代表当前时刻的全局唯一的id(非空字符串,不包含空格,可假设它一定是全局唯一的)
2、第二行是当前的时刻。格式为yyyy/MM/dd HH:mm:ss (如2016/12/01 23:04:09)
3、从第三行开始是各动物的坐标变化,一个动物占用一行。这种变化有两种形式:
(1)第一种形式:{动物的ID}{x坐标}{y坐标}。这种形式说明这种动物第一次出现在了这个区域里;
(2)第二种形式:{动物的id}{上一个时刻的x坐标}{上一个时刻的y坐标}{x坐标变化量}{y坐标的变化量}。这种形式说明该动物在之前已经位于这个区域里了,其上一个时刻的x坐标和y坐标用于进行校验。而x,y坐标的变化为整数,正数表示增加,负数表示减少。
3、所有的数据全部存储在一个字符串 historyData 中。
例如:
e4e87cb2-8e9a-4749-abb6-26c59344dfee
2016/09/02 22:30:46
cat1 10 9

351055db-33e6-4f9b-bfe1-16f1ac446ac1
2016/09/02 22:30:52
cat1 10 9 2 -1
cat2 2 3

dcfa0c7a-5855-4ed2-bc8c-4accae8bd155
2016/09/02 22:31:02
cat1 12 8 3 4

要求

请编写函数,其输入是上述数据字符串,和当前时刻的ID,输出为字符串。
注意,你可以对该函数的实现进行任意的设置。例如,划分子函数或创建新的类型。

输出该ID代表的时刻的所有动物的坐标快照

输出某一个ID代表的时刻的所有动物的坐标快照。并将坐标按照{动物ID}{x}{y}格式舒服。输出时按 动物ID升序排序。

例如,针对范例历史数据,当ID为 dcfa0c7a-5855-4ed2-bc8c-4accae8bd155 时,输出内容如下:

cat1 15 12
cat2 2 3

输入验证信息

程序应当验证输入的有效性。
1、当 historyData的格式不符合要求时请输出
Invalid format.
2、若historyData 数据存在问题,例如对于一下的文本
e4e87cb2-8e9a-4749-abb6-26c59344dfee
2016/09/02 22:30:46
cat1 10 9

351055db-33e6-4f9b-bfe1-16f1ac446ac1
2016/09/02 22:30:52
cat1 10 9 2 -1
cat2 2 3

dcfa0c7a-5855-4ed2-bc8c-4accae8bd155
2016/09/02 22:31:02
cat1 11 8 3 4

则输出为
Conflict found at dcfa0c7a-5855-4ed2-bc8c-4accae8bd155
如果多余一个的错误,则只需要输出第一个错误即可。

解题思路

主要分为三步:
1、首先校验数据是否符合格式;
2、判断动物的坐标数据是否正确;
3、根据ID输出当前所有动物的位置数据

代码

historyData:存储所有字符串
id:当前时刻的ID
通过输入historyData和ID来获在该时刻动物的所有坐标快照

public static String getSnapShot(String historyData, String id){
        //将数据进行按空行分割
        String[] str = historyData.split("\n\r\n");
        List<Map<String, String>> list = new ArrayList<>();//用来记录动物
        for (int i=0;i<str.length;i++){
            //将每一时刻的数据进行校验,看是否符合规范;
            boolean b = isValids(str[i]);
            if (!b){//若返回false,则校验不成功。
                return "Invalid format.";
            }
            //验证数据是否存在问题
            list = isQuestion(str[i], list);
            for (int j=0;j<list.size();j++){
                if (list.get(j).containsKey("question")){
                    return list.get(j).get("question");
                }
            }
        }
        List<Map<String, String>> recodList = new ArrayList<>();//记录动物
        StringBuilder sb = new StringBuilder();//用于输出字符数据
         //根据ID获取数据
        for (int i=0;i<str.length;i++){
            recodList = recodAnimal(str[i],recodList);
            String[] str4 = str[i].split("\n");
            //根据ID来判断需要输出的数据是什么
            if (id.equals(str4[0])){
                for (Map<String, String> map : recodList){
                    for (String k : map.keySet()){
                        sb.append(k + " " +map.get(k) + "\n");
                    }
                }
            }
        }
        return sb.toString();
    }

通过输入每一时刻动物快照的数据,来进行校验
1、判断第一行全局ID是否为空字符串,并且不能包含空字符串
2、判断第二行当前时刻的格式是否正确
3、判断动物坐标数据是否符合规则
4、若上面三种情况其中一个不符合,返回false

  /**
     *  每一时刻的数据进行校验
     */
    public static boolean isValids(String str) {
        String[] str1 = str.split("\n");
        if(str1.length < 3){
            return  false;
        }
        //判断全局ID是否为空,若是返回false
        if (StringUtils.isEmpty(str1[0]) || str1[0].contains(" ")){
            return false;
        }
        //判断时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        boolean b = true;
        try {
            sdf.parse(str1[1]);
        } catch (ParseException e) {
            b = false;
        }
        if (!b){
            return false;
        }
        // 判断动物坐标是否正确
        for(int i=2;i<str1.length;i++){
            String[] str2 = str1[i].split(" ");
            if (str2.length == 3 || str2.length == 5){//判断长度是否符合
                for (int j = 1;j<str2.length;j++){
                    //判断是否为整数
                    boolean b1 = isNumber(str2[j]);
                    if (b1 == false){
                        return false;
                    }
                }
            }else {
                return false;
            }

        }
        return true;
    }

    //判断是否是数字
    public static boolean isNumber(String s){
        return s.matches("-?[0-9]+");
    }


通过输入每一时刻动物快照数据和上一个动物的坐标list,来校验该时刻动物原始坐标数据是否正确

/**
     * 问题验证
     * */
    public static List<Map<String, String>> isQuestion(String str, List<Map<String, String>> list){
        List<Map<String, String>> list1 = new ArrayList<>();
        String[] str3 = str.split("\n");
        if (list.size() == 0){//代表插入第一个数据
            for (int i=2;i<str3.length;i++){
                Map<String, String> map = new HashMap<>();
                String[] s = str3[i].split(" ");
                map.put(s[0], str3[i]);
                list1.add(map);
            }
        }else {
            for (int i=2;i<str3.length;i++){
                Map<String, String> map = new HashMap<>();
                String[] s = str3[i].split(" ");
                for (int j=0;j<list.size();j++){
                    if(list.get(j).containsKey(s[0])){
                        String[] s1 = list.get(j).get(s[0]).split(" ");
                        int x = 0,y = 0;
                        if (s1.length ==5) {
                             x = Integer.valueOf(s1[1]) + Integer.valueOf(s1[3]);//x坐标值
                             y = Integer.valueOf(s1[2]) + Integer.valueOf(s1[4]);//y坐标值
                        }else {
                            x = Integer.valueOf(s1[1]);
                            y = Integer.valueOf(s1[2]);
                        }
                        int x1 = Integer.valueOf(s[1]);
                        int y1 = Integer.valueOf(s[2]);
                        //判断x,y坐标是否一致
                        if (x != x1 || y != y1){
                             map.put("question", "Conflict found at " + str3[0]);
                            list1.add(map);
                        }
                    }
                }
                //将数据放入map中
                map.put(s[0], str3[i]);
                list1.add(map);
            }
        }
        return list1;
    }

通过输入每一时刻动物的快照数据和上一时刻动物坐标的数据list
1、如果list是第一次记录,则直接将数据加入;
2、获取这个时刻动物的坐标数据,判断该动物是否存储在list中,若存在,更新list中的动物数据,否则加入list中

/**
     * 记录动物的坐标
     * */
    public static List<Map<String, String>> recodAnimal(String str, List<Map<String, String>> list){
        String[] str3 = str.split("\n");
        int index = list.size();
        if (index == 0) {//当list为空时
            for (int i = 2; i < str3.length; i++) {
                String[] s = str3[i].split(" ");
                StringBuilder sb = new StringBuilder();
                Map<String, String> map = new HashMap<>();
                map.put(s[0], sb.append(s[1] + " " + s[2]).toString());
                list.add(map);
            }
        }else {//非空时
            for (int i = 2; i < str3.length; i++) {
                StringBuilder sb = new StringBuilder();
                Map<String, String> map = new HashMap<>();
                String[] s = str3[i].split(" ");
                for (int j = 0; j < index; j++) {
                    if (list.get(j).containsKey(s[0])) {
                        int x = Integer.valueOf(s[1]) + Integer.valueOf(s[3]);//x坐标值
                        int y = Integer.valueOf(s[2]) + Integer.valueOf(s[4]);//y坐标值
                        list.get(j).replace(s[0], sb.append(x + " " + y).toString());
                        break;
                    } else {
                        map.put(s[0], sb.append(s[1] + " " + s[2]).toString());
                        list.add(map);
                    }

                }


            }
        }
        return list;
    }

测试

正确的数据测试

 public static void main(String[] args) {

        StringBuilder history = new StringBuilder();
        history.append("e4e87cb2-8e9a-4749-abb6-26c59344dfee\n");
        history.append("2016/09/02 22:30:46\n");
        history.append("cat1 10 9\n");
        history.append("\r\n");
        history.append("351055db-33e6-4f9b-bfe1-16f1ac446ac1\n");
        history.append("2016/09/02 22:30:52\n");
        history.append("cat1 10 9 2 -1\n");
        history.append("cat2 2 3\n");
        history.append("\r\n");
        history.append("dcfa0c7a-5855-4ed2-bc8c-4accae8bd155\n");
        history.append("2016/09/02 22:31:02\n");
        history.append("cat1 12 8 3 4\n");

        String s = getSnapShot(history.toString(), "dcfa0c7a-5855-4ed2-bc8c-4accae8bd155");
        System.out.println(s);

    }

返回

com.spring.startlean.main
cat1 15 12
cat2 2 3


Process finished with exit code 0

时间格式错误:
如:2016-09-02 22:30:46

    public static void main(String[] args) {

        StringBuilder history = new StringBuilder();
        history.append("e4e87cb2-8e9a-4749-abb6-26c59344dfee\n");
        history.append("2016-09-02 22:30:46\n");
        history.append("cat1 10 9\n");
        history.append("\r\n");
        history.append("351055db-33e6-4f9b-bfe1-16f1ac446ac1\n");
        history.append("2016/09/02 22:30:52\n");
        history.append("cat1 10 9 2 -1\n");
        history.append("cat2 2 3\n");
        history.append("\r\n");
        history.append("dcfa0c7a-5855-4ed2-bc8c-4accae8bd155\n");
        history.append("2016/09/02 22:31:02\n");
        history.append("cat1 12 8 3 4\n");

        String s = getSnapShot(history.toString(), "dcfa0c7a-5855-4ed2-bc8c-4accae8bd155");
        System.out.println(s);

    }

返回

Invalid format.

Process finished with exit code 0

historyData存在问题,如:
e4e87cb2-8e9a-4749-abb6-26c59344dfee
2016/09/02 22:30:46
cat1 10 9

351055db-33e6-4f9b-bfe1-16f1ac446ac1
2016/09/02 22:30:52
cat1 10 9 2 -1
cat2 2 3

dcfa0c7a-5855-4ed2-bc8c-4accae8bd155
2016/09/02 22:31:02
cat1 11 8 3 4

 public static void main(String[] args) {

        StringBuilder history = new StringBuilder();
        history.append("e4e87cb2-8e9a-4749-abb6-26c59344dfee\n");
        history.append("2016/09/02 22:30:46\n");
        history.append("cat1 10 9\n");
        history.append("\r\n");
        history.append("351055db-33e6-4f9b-bfe1-16f1ac446ac1\n");
        history.append("2016/09/02 22:30:52\n");
        history.append("cat1 10 9 2 -1\n");
        history.append("cat2 2 3\n");
        history.append("\r\n");
        history.append("dcfa0c7a-5855-4ed2-bc8c-4accae8bd155\n");
        history.append("2016/09/02 22:31:02\n");
        history.append("cat1 11 8 3 4\n");

        String s = getSnapShot(history.toString(), "dcfa0c7a-5855-4ed2-bc8c-4accae8bd155");
        System.out.println(s);

    }

返回

Conflict found at dcfa0c7a-5855-4ed2-bc8c-4accae8bd155

Process finished with exit code 0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!