目录
原题OJ平台链接:https://www.lanqiao.cn/problems/283/learning
1、题目内容:
2、解题思路
此题为模拟类题目,难点主要集中在小车方向的描述以及字符串指令的分解,对于这两个问题,我是这样思考以及解决的:
2.1、小车方向描述:
小车的方向共有四种,分别对应平面坐标系中x轴和y轴坐标的变化,转向指令R代表顺时针旋转90°,转向指令L代表逆时针旋转90°如图1所示:
图一:方向描述示意图
因此可以定义描述方向的数组,四个下标对应四种方向,并且每个方向中记录了其对应顺时针以及逆时针方向的下标,检测到转向指令后便修改方向,具体实现如以下代码:
public class 机器人行走 {
static int[][] dirs = { { 3, 1 }, { 0, 2 }, { 1, 3 }, { 2, 0 } }; //方向描述
static int[] dir = dirs[0]; //当前方向
static int[] cor = { 0, 0 }; //当前坐标
static int dis = 0; //前进距离
//初始化
public static void init() {
cor[0] = 0;
cor[1] = 0;
dir = dirs[0];
dis = 0;
}
//修改方向
public static void direction(char k) {
if (k == 'R')
dir = dirs[dir[1]];
if (k == 'L')
dir = dirs[dir[0]];
}
//移动
public static void move(int dis) {
if (dir == dirs[0])
cor[1] += dis;
if (dir == dirs[1])
cor[0] += dis;
if (dir == dirs[2])
cor[1] -= dis;
if (dir == dirs[3])
cor[0] -= dis;
}
}
2.2、字符串指令分解
2.2.1、正则表达式法
起初我使用正则表达式对输入的字符串进行分解,实现的过程十分的麻烦,我曾在C语言环境下使用过正则表达式对文件路径进行了分解,在这里贴一个菜鸟教程的在线编辑器,代码如下:
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class 正则表达式 {
//匹配以“转向命令(L||R)+移动距离”的情况
static String pattern_dd = "([L,R]\\d*)";
static Pattern r_dd = Pattern.compile(pattern_dd);
static Matcher m_dd;
//匹配以“移动距离+转向命令(L||R)”的情况
static String pattern_d = "(\\d*)[L,R]";
static Pattern r_d = Pattern.compile(pattern_d);
static Matcher m_d;
public static ArrayList<String> find_Order(String str_dd) {
ArrayList<String> orders = new ArrayList<String>();
m_dd = r_dd.matcher(str_dd);
m_d = r_d.matcher(str_dd);
if (Character.isDigit(str_dd.charAt(0))) {
m_d.find();
orders.add(m_d.group(1));
}
while (m_dd.find())
orders.add(m_dd.group(0));
return orders;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
String order[] = new String[n];
for (int i = 0; i < n; i++) {
order[i] = scan.next();
}
scan.close();
for (int i = 0; i < n; i++) {
ArrayList<String> orders = find_Order(order[i]);
System.out.println(orders);
}
}
}
2.2.2、数组分解法
在阅览众多大佬使用的方法之后,发现我使用方法的笨拙,可以将字符串转换为数组进行分解,方法十分巧妙,如下:
import java.util.Scanner;
public class 机器人行走 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
String order[] = new String[n];
for (int i = 0; i < n; i++) {
order[i] = scan.next();
}
scan.close();
for (int i = 0; i < n; i++) {
init();
char[] temp = order[i].toCharArray();
int j = 0;
while (j < temp.length) {
// 确定方向
if (temp[j] == 'L' || temp[j] == 'R')
direction(temp[j++]);
// 确定移动距离,这里加下标长度的判断是为了避免数组越界
while (j < temp.length && Character.isDigit(temp[j]))
dis = dis * 10 + temp[j++] - '0';
// 执行移动
if (dis != 0) {
move(dis);
dis = 0;
}
}
// 计算距离,输出结果
double length = Math.sqrt(Math.pow(cor[0], 2) + Math.pow(cor[1], 2));
System.out.printf("%.2f\n", length);
}
}
static int[][] dirs = { { 3, 1 }, { 0, 2 }, { 1, 3 }, { 2, 0 } };
static int[] dir = dirs[0];
static int[] cor = { 0, 0 };
static int dis = 0;
public static void init() {
cor[0] = 0;
cor[1] = 0;
dir = dirs[0];
dis = 0;
}
public static void direction(char k) {
if (k == 'R')
dir = dirs[dir[1]];
if (k == 'L')
dir = dirs[dir[0]];
}
public static void move(int dis) {
if (dir == dirs[0])
cor[1] += dis;
if (dir == dirs[1])
cor[0] += dis;
if (dir == dirs[2])
cor[1] -= dis;
if (dir == dirs[3])
cor[0] -= dis;
}
}