【编程题】(满分18分)
某少年宫引进了一批机器人小车。可以接受预先输入的指令,按指令行动。小车的基本动作很简单,只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字)。
例如,我们可以对小车输入如下的指令:
15L10R5LRR10R20
则,小车先直行15厘米,左转,再走10厘米,再右转,...
不难看出,对于此指令串,小车又回到了出发地。
你的任务是:编写程序,由用户输入指令,程序输出每条指令执行后小车位置与指令执行前小车位置的直线距离。
【输入、输出格式要求】
用户先输入一个整数n(n<100),表示接下来将有n条指令。
接下来输入n条指令。每条指令只由L、R和数字组成(数字是0~100之间的整数)
每条指令的长度不超过256个字符。
程序则输出n行结果。
每条结果表示小车执行相应的指令前后位置的直线距离。要求四舍五入到小数后2位。
例如:用户输入:5L100R50R103LLL5RR4L12LL100R5L5L5L5
则程序输出:102.969.060.00100.000.00
代码如下:
import java.util.Scanner;
public class MovingProcessor {
//所谓四面八方,把方向控制好就行了
//以2维坐标为参考,前为上(y坐标增加),右为右(x坐标增加),后为下(y坐标减少),左为左(x坐标减少)
private static final int[][] MOVING_DIR = {{0,1}, {1,0}, {0,-1}, {-1,0}};
protected int dir = 0; //用于控制方向
protected double x = 0; //用于控制x坐标
protected double y = 0; //用于控制y坐标
private boolean isolating = true; //是否是独立的命令(用于扩展,此题可忽略),因为是每次独立计算距离(即后面的距离不累加前面的距离),所以本题设为独立命令
//private boolean realTime = false;//是否是实时处理(用于扩展,此题忽略)
public MovingProcessor() {}
public MovingProcessor(boolean isolating) {
this.isolating = isolating;
}
public void reset() { //处理器重置
dir = 0;
x = 0;
y = 0;
}
public double execute(String cmd) throws Exception { //执行指令,支持小数距离(题目给的是整数距离,这里扩展支持小数距离)
if (isolating) reset();
double num = 0, times = 0;
for (char c : cmd.toCharArray()) { //按字符遍历指令
if (c == 'L') { //遇到左转L指令
if (num > 0) {//判断是否L指令前是否存在移动距离,如果存在,则先移动
move(num); //移动距离
num = 0;
}
changeDir(c); //改变方向
} else if (c == 'R') { //遇到R右转指令
if (num > 0) {
move(num);
num = 0;
}
changeDir(c);
} else if (c>='0' && c<='9') { //遇到数字累加数字
num = num*10 + (c-'0');
}
}
if (num > 0) { //如果有移动距离就移动
move(num);
}
return Math.sqrt(x*x + y*y); //返回移动的距离
}
protected void changeDir(char dir) { //改变方向
this.dir += (dir=='L' ? -1 : (dir=='R' ? 1 : 0));
}
protected void move(double value) { //移动距离
dir %= 4;
dir += (dir < 0) ? 4 : 0;
x += value * MOVING_DIR[dir][0];
y += value * MOVING_DIR[dir][1];
}
public static void main(String[] args) {
String[] cmds = getCmds();
MovingProcessor mp = new MovingProcessor();
System.out.println("Execute Result:");
for (String cmd : cmds) {
try {
System.out.printf("%.2f\n", mp.execute(cmd));
} catch (Throwable e) {
e.printStackTrace();
//break; //skip, ignore, cancel, so on...
}
}
}
public static String[] getCmds() {
System.out.println("请输入n(整数n<100)条指令:");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String[] cmd = new String[n];
for (int i = 0; i < cmd.length; i++) {
cmd[i]=scanner.next();
if(!checkCmd(cmd[i])){//检查指令
System.out.println("指令错误!请输入L、R、数字");
System.exit(0);
}
}
return cmd;
}
public static boolean checkCmd(String s){
boolean flag=false;
for (int i = 0; i < s.length(); i++) {
if((s.charAt(i)<='9'&&s.charAt(i)>='0')||(s.charAt(i)=='L'||s.charAt(i)=='R')){
flag=true;
}else {
flag=false;
break;
}
}
return flag;
}
}