面试小记---孤独的太空漫游车

梦想的初衷 提交于 2020-02-25 00:33:04

为了不掉线,最近要补补.

  • 其一:面试题,
  • 其二:基础知识.
  • 其三:洗干净眼睛,好好看

昨晚在浙大门口摔了一跤,直到今天上午,腿脚一直不变,膝盖肿成了西瓜,苦逼就是在下了,摔倒爬起就跑,可真是丢脸了.年纪大了,容易碎碎念,请看下面题目.

题目:

一队机器人漫游车将被美国宇航局降落在火星高原上。漫游车将在这个奇怪的长方形高原上巡游,以便他们的机载摄像头可以获得周围地形的完整视图,并将其发送回地球。
漫游者的坐标和位置由x和y坐标的组合以及代表四个方向(E, S, W, N)的字母表示。高原划分为网格以简化导航。比如位置0,0,N,表示漫游车位于左下角并面向北。
为了控制漫游车,美国宇航局发送一串简单的字母。指令字母是'L','R'和'M'。 
'L'和'R'使漫游车分别向左或向右旋转90度,而不会从当前地点移动。 'M'表示前进一个网格点,并保持相同的方向。
假设从(x,y)直接向北移动,就到了(x,y + 1)。
INPUT:

第一行输入是平台的右上角坐标,左下角坐标被假定为0,0。

其余的输入是有关已部署的漫游车的信息。每个漫游车都有两行输入。第一行给出了漫游车的位置,第二行是告诉漫游车如何探索高原的一系列指令。位置由两个整数和一个由空格分隔的字母组成,对应于x和y坐标以及漫游车当前的方向。

每个漫游车将按顺序完成,这意味着第二个漫游车在第一个漫游车完成移动之前不会开始移动。

OUTPUT:

每个漫游车的输出应该是其最终的坐标和位置。

输入输出例子

输入:

5 5

1 2 N

LMLMLMLMM

3 3 E

MMRMMRMRRM

预期产出:

1 3 N

5 1 E

  

我的思路:

  其中无非是根据小车的位置和方向,来执行小车的行为轨迹,其中方向确定这个是问题,还有就是更具方向在确定行动方向这个也就好办了,我觉的最主要的就是得到小车的当前的方向,然后在进行计算.

首先先封装小车:

@Data
@AllArgsConstructor
class Point {
    private int x;
    private int y;
}

@Data
class Car{
    private Point posintion;
    private int direction;

    public Car(Point posintion, int direction) throws Exception {
        if(!Objects.isNull(posintion) && !VisitorCar.isCrossing(posintion)){
            throw new Exception("小车位置初始化失败!");
        }
        this.posintion = posintion;
        this.direction = direction;
    }
}

这里用到一个插件lombok,可以了解下,这个东东超级好用.

既然这样,我想先把方向封装起来,如下:

interface BaseDirection{
    int getKey();
    String getValue();
}

enum Direction implements BaseDirection{
    E(360,"E"),N(90,"N"),W(180,"W"),S(270,"S");

    private int key;
    private String value;

    Direction(int key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public int getKey() {
        return key;
    }
    @Override
    public String getValue() {
        return value;
    }
}

 

根据角度计算方向值.先将输入的方向值转换成角度在计算,这就好计算了,看是向左向右,无非是加上360后在取余从而获取其角度计算其方向,在根据其方向,决定下次移动的时候是的坐标位置操作.

比如:

(1,,2,90) == (1,2) N

左转:

L 操作后: (1,2,180)

M操作后: (0,2,180)

L 操作后: (0,2,270)

M 操作后: (0,1,180)

右转:

R 操作后: (1,2,0)

M操作后: (2,2,0)

R 操作后: (2,2,-90)

M 操作后: (2,1,-90)

  

这样操作起来就很容易了.代码如下:

/** * 根据角度获取方向参数 * * @param key * @return */private static String getPosition(int key){    if(key < 0){ key = 360+key; }    Direction[] values = Direction.values();    key = (key == 0 || key == 360? 360:key%360);    for (Direction d : values){        int key1 = Direction.valueOf(d.getValue()).getKey();        if(key1 == key) {            return d.getValue();        }    }    return null;}

接下来就是小车的具体操作了:

    /**
     * 操作小车
     *
     * @param car
     * @param operate
     * @return
     */
    private static Car operateCar(Car car, String operate) throws Exception {
        //获取小车方向
        int direction = car.getDirection();
        //获取小车位置
        Point positionXY = car.getPosintion();
        int endDirection = 0;
        char[] chars = operate.toCharArray();
        for (char aChar : chars) {
            switch (aChar){
                case 'L':
                    direction += 90;
                    break;
                case 'R':
                    direction -= 90;
                    break;
                case 'M':
                    int x = positionXY.getX();
                    int y = positionXY.getY();
                    String position = getPosition(direction);
                    switch (position){
                        case "E":
                            positionXY.setX(x+1);
                            break;
                        case "W":
                            positionXY.setX(x-1);
                            break;
                        case "N":
                            positionXY.setY(y+1);
                            break;
                        case "S":
                            positionXY.setY(y-1);
                            break;
                            default:
                                System.out.println("移动小车失败!");
                                break;
                    }
                    break;
                default:
                    break;
            }
            endDirection = direction;
        }
        return new Car(positionXY,endDirection);
    } 

 

好了,主要逻辑代码就写完了,是不是很简单呢!放出完整的程序:

 

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Objects;
import java.util.Scanner;

/**
 * @author: zhangyi
 * @date: 2019/4/17 22:12
 * @description:
 */
public class VisitorCar {

    public static final String SPIL = " ";


    public static final Point minPoint = new Point(0,0);


    public static final Point maxPoint = new Point(0,0);

    /**
     *
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Car car = null;
        Scanner scanner = new Scanner(System.in);
        //获取输入
        System.out.println("输入坐标网格最大坐标:");
        String s = scanner.nextLine();
        Integer[] integers = paseInts(s.split(SPIL));
        if(!Objects.isNull(integers) && integers.length == 2){
            maxPoint.setX(integers[0]);
            maxPoint.setY(integers[1]);
        }

        System.out.println("输入需要小车个数:");
        Integer carCount = Integer.parseInt(scanner.nextLine().trim());
        for (Integer integer = 0; integer < carCount; integer++) {
            Car carEnd = moveCar(scanner, car,integer);
            int direction = carEnd.getDirection();
            Point posintion = carEnd.getPosintion();
            int x = posintion.getX();
            int y = posintion.getY();
            String position = getPosition(direction);
            System.out.println(x+" "+y+" "+position);
        }
    }
    /**
     * 车移动操作
     *
     * @return
     */
    private static Car moveCar(Scanner scanner,Car car,int index) throws Exception {
        System.out.println("输入第"+(index+1)+"初始化小车位置+方向:");
        String carPoint = scanner.nextLine();
        if(!Objects.isNull(carPoint)){
            Integer[] pos = paseInts(carPoint.split(SPIL));
            car = new Car(new Point(pos[0],pos[1]),pos[2]);
        }
        System.out.println("输入第"+(index+1)+"小车操作指令:");
        String operate = scanner.nextLine();
        Car carEnd = operateCar(car,operate);
        return carEnd;
    }

    /**
     * 根据角度获取方向参数
     *
     * @param key
     * @return
     */
    private static String getPosition(int key){
        if(key < 0){ key = 360+key; }
        Direction[] values = Direction.values();
        key = (key == 0 || key == 360? 360:key%360);
        for (Direction d : values){
            int key1 = Direction.valueOf(d.getValue()).getKey();
            if(key1 == key) {
                return d.getValue();
            }
        }
        return null;
    }
    /**
     * 操作小车
     *
     * @param car
     * @param operate
     * @return
     */
    private static Car operateCar(Car car, String operate) throws Exception {
        //获取小车方向
        int direction = car.getDirection();
        //获取小车位置
        Point positionXY = car.getPosintion();
        int endDirection = 0;
        char[] chars = operate.toCharArray();
        for (char aChar : chars) {
            switch (aChar){
                case 'L':
                    direction += 90;
                    break;
                case 'R':
                    direction -= 90;
                    break;
                case 'M':
                    int x = positionXY.getX();
                    int y = positionXY.getY();
                    String position = getPosition(direction);
                    switch (position){
                        case "E":
                            positionXY.setX(x+1);
                            break;
                        case "W":
                            positionXY.setX(x-1);
                            break;
                        case "N":
                            positionXY.setY(y+1);
                            break;
                        case "S":
                            positionXY.setY(y-1);
                            break;
                            default:
                                System.out.println("移动小车失败!");
                                break;
                    }
                    break;
                default:
                    break;
            }
            endDirection = direction;
        }
        return new Car(positionXY,endDirection);
    }

    /**
     * 字符串数组转化
     *
     * @param strs
     * @return
     */
    private static Integer[] paseInts(String[] strs){
        Integer[] integers = new Integer[strs.length];
        for (int i = 0; i < strs.length; i++) {
            switch (strs[i]){
                case "E":
                case "W":
                case "S":
                case "N":
                    integers[i] = Direction.valueOf(strs[i]).getKey();
                    break;
                    default:
                        integers[i] = Integer.parseInt(strs[i]);
                        break;
            }
        }
        return integers;
    }
    /**
     * 越界处理
     *
     * @param point
     * @return
     */
    public static boolean isCrossing(Point point){
        return point.getX() <= maxPoint.getX() && point.getY() <= maxPoint.getY();
    }

}



@Data
@AllArgsConstructor
class Point {
    private int x;
    private int y;
}

@Data
class Car{
    private Point posintion;
    private int direction;

    public Car(Point posintion, int direction) throws Exception {
        if(!Objects.isNull(posintion) && !VisitorCar.isCrossing(posintion)){
            throw new Exception("小车位置初始化失败!");
        }
        this.posintion = posintion;
        this.direction = direction;
    }
}

interface BaseDirection{
    int getKey();
    String getValue();
}

enum Direction implements BaseDirection{
    E(360,"E"),N(90,"N"),W(180,"W"),S(270,"S");

    private int key;
    private String value;

    Direction(int key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public int getKey() {
        return key;
    }
    @Override
    public String getValue() {
        return value;
    }
}

  结果:

还需要优化的地方:

输入参数校验可以在做些比较.

我这里并不是安装题目要求的输入全部指定后在进行一个一个操作,为啥?可以把小车操作封装起来,在一个集合中按照次序操作,腿痛死了......暂时写到这咯.

 

 

小车结尾,-__-,Thank you for seeing here, I hope you will come again next time.

 

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