要学习的知识点
- 模拟算法与状态更新
- 字符串遍历
- 字典映射方向
- 元组解包
- continue 控制循环
题目
练习 7:模拟 U/D/L/R 方向移动,输出终点坐标和移动步数。
坐标约定:向右 x+1,向左 x-1,向上 y+1,向下 y-1。
输入一行由 U、D、L、R 组成的方向序列。
完整代码
以下内容与 ex07.py 一致,可对照右侧讲解阅读。
"""练习 7:模拟 U/D/L/R 方向移动,输出终点坐标和移动步数。
坐标约定:向右 x+1,向左 x-1,向上 y+1,向下 y-1。
输入一行由 U、D、L、R 组成的方向序列。
学习说明:
- strip() 去掉首尾空白,upper() 让小写指令也可以使用。
- x、y 从原点 (0, 0) 开始;moves 字典把方向映射到坐标变化量 (dx, dy)。
- for 循环逐个读取指令;不认识的字符跳过,合法指令则更新坐标和步数。
- 最终坐标表示位置;steps 统计实际执行的有效移动数。
"""
directions = input().strip().upper()
x = y = steps = 0
moves = {"U": (0, 1), "D": (0, -1), "L": (-1, 0), "R": (1, 0)}
for direction in directions:
if direction not in moves:
continue
dx, dy = moves[direction]
x += dx
y += dy
steps += 1
print("position:", x, y)
print("steps:", steps)
进阶写法
这版与初学版解决同一道题,使用更精炼的语法或标准库工具。
进阶源码:ex07_adv.py
"""练习 7 进阶版:用生成器表达式分别累计横纵坐标变化。"""
directions = input().strip().upper()
moves = {"U": (0, 1), "D": (0, -1), "L": (-1, 0), "R": (1, 0)}
x = sum(moves[direction][0] for direction in directions if direction in moves)
y = sum(moves[direction][1] for direction in directions if direction in moves)
steps = sum(1 for direction in directions if direction in moves)
print("position:", x, y)
print("steps:", steps)
生成器表达式逐条提供合法方向的坐标变化量,sum() 分别求横向和纵向总变化;第三个 sum() 统计有效指令数。
运行结果
示例输入:
URRDL程序输出:
position: 1 0
steps: 5逐个认识函数
下表根据程序中实际调用的函数和方法整理;自定义函数的实现与算法细节见后续说明。
| 函数形式 | 功能与返回值 | 注意事项 |
|---|---|---|
input(prompt='') | 读取一行文本,返回 str;若提供 prompt 会先显示提示。 | 返回值默认是字符串,计算前通常要做类型转换。 |
str.strip(chars=None) | 返回去掉首尾空白或指定字符的新字符串。 | 不会删除字符串中间的字符。 |
str.upper() | 返回转成大写的新字符串。 | 原字符串不变。 |
print(*objects, sep=' ', end='\n') | 把对象转换为文本显示;返回 None。 | 默认空格分隔并在末尾换行。 |
算法原理:维护当前状态
把位置 (x, y) 看作游戏角色当前状态。每条指令对应一个变化量:U 是 (0,1),R 是 (1,0) 等。拿到一条指令就把变化量加到坐标上。整个循环结束时,变量保存的就是终点。
- 读入整串指令,去掉首尾空白并统一大写。
- 初始化位置和步数为 0,建字典记录方向对应的坐标变化。
- 逐字符查字典;非法字符按程序约定跳过。
- 将 dx、dy 加到 x、y,并把有效步数加 1。
本题用到的方法
| 写法 | 参数与返回值 | 用法提示 |
|---|---|---|
input() | 读一行,返回字符串。 | 本程序把整行当方向序列。 |
str.strip() | 默认移除字符串首尾空白,返回新字符串。 | 不会删除中间字符。 |
str.upper() | 返回大写形式的新字符串。 | 让 u/r 也能作为合法指令;原字符串不被修改。 |
dict[key] | 按键取对应值;键不存在时会报 KeyError。 | 因此程序先用 if direction not in moves 检查,再取值。 |
print(...) | 显示一个或多个对象,返回 None。 | 两个坐标变量分别输出,中间默认空格。 |
字典的值是二元组,如 (0, 1)。dx, dy = moves[direction] 称为解包,按位置把两个元素分别赋给变量。
重要约定与变化
程序只统计合法的四个方向;其他字符使用 continue 跳过本轮循环,既不改变坐标也不增加步数。若题目要求非法输入报错,就要把 continue 改成错误提示或异常。
试试指令 URDL:走一圈后回到 (0,0),但步数仍是 4。位置和已走步数是两种不同信息。
代码如何运行
- 先按左侧题目给出的格式输入数据;程序通过 input() 读取,并在需要时转换数据类型。
- 程序自上而下执行语句;遇到条件、循环或函数调用时,按照右侧算法说明更新变量和处理数据。
- 最后由 print() 输出计算结果。可将左侧示例输入与输出逐项对照。
先自己跟踪一组小数据,记录循环前后变量的值;这比只看最终答案更容易理解程序。
自己动手试一试
试试 URDL 回到原点但步数增加;输入小写方向或非法字符,观察程序的约定。
先在 lx07.py 中独立完成,再运行参考程序比较结果。修改程序时一次只改一个条件或步骤。