轨道
/
Prolog
Prolog
/
练习
/
全球定位系统
全球定位系统

全球定位系统

中等

简介

你是地理寻宝的超级粉丝,这项活动把你对户外的热爱和对解谜的热爱结合在了一起。 当地的寻宝网站列出了所有藏宝点的 GPS 坐标,却_不_支持规划一条高效收集它们的路线。 碰巧你的机器上装了寻路软件,但它使用的 GPS 格式与寻宝网站不同。 要把数据输入寻路软件,你需要解析网站上每个 GPS 坐标的纬度和经度的度数与半球。

说明

你的任务是解析 GPS 坐标。每个坐标都采用十进制度数格式的变体,并显式标注半球:

<LATITUDE_DEGREES> <LATITUDE_HEMISPHERE>, <LONGITUDE_DEGREES> <LONGITUDE_HEMISPHERE>

每个组成部分的允许取值如下:

  • <LATITUDE_DEGREES>:范围 0..90(含)内的浮点数
  • <LATITUDE_HEMISPHERE>:N或S
  • <LONGITUDE_DEGREES>:范围 0..180(含)内的浮点数
  • <LONGITUDE_HEMISPHERE>:E或W

例如,"48.8584 N, 2.2945 E"解析为:

  • <LATITUDE_DEGREES>:48.8584
  • <LATITUDE_HEMISPHERE>:N
  • <LONGITUDE_DEGREES>:2.2945
  • <LONGITUDE_HEMISPHERE>:E

共有 11 个任务,你将逐步解析 GPS 坐标。你会用到 Prolog 的定子句文法(DCG)支持,它正是为解析结构化文本而设计的。

Note

为了帮你上手,存根文件已经通过下面的代码引入了dcg/basics库:

:- use_module(library(dcg/basics)).

1. 解析逗号

实现comma规则来解析单个逗号(","):

?- string_codes(",", Codes), phrase(comma, Codes).

2. 解析空格

实现space规则来解析单个空格(" "):

?- string_codes(" ", Codes), phrase(space, Codes).

3. 支持所有空白字符(换行符除外)

修改space规则,让它解析所有空白字符,但不解析换行符:

?- string_codes("\t", Codes), phrase(space, Codes).

?- string_codes("\n", Codes), phrase(space, Codes).
false.

4. 解析纬度的半球

纬度的半球可以是"N"或"S",它们应被解析为north或south原子。实现latitude_hemisphere规则来解析纬度的半球:

?- string_codes("N", Codes), phrase(latitude_hemisphere(Hemisphere), Codes).
Hemisphere = north.

5. 解析经度的半球

经度的半球可以是"E"或"W",它们应被解析为east或west原子。实现longitude_hemisphere规则来解析经度的半球:

?- string_codes("E", Codes), phrase(longitude_hemisphere(Hemisphere), Codes).
Hemisphere = east.

6. 解析度数

经度或纬度的度数被定义为浮点数。实现degrees规则来解析浮点数:

?- string_codes("748.012", Codes), phrase(degrees(Degrees), Codes).
Degrees = 748.012.

7. 解析纬度度数

纬度度数不只是普通的浮点数,而是范围 0..90(含)内的浮点数。实现latitude_degrees规则,用上面的范围来解析纬度度数:

?- string_codes("48.745", Codes), phrase(latitude_degrees(Degrees), Codes).
Degrees = 48.745.

?- string_codes("117.844", Codes), phrase(latitude_degrees(Degrees), Codes).
false.

8. 解析经度度数

经度度数不只是普通的浮点数,而是范围 0..180(含)内的浮点数。实现longitude_degrees规则,用上面的范围来解析经度度数:

?- string_codes("178.773", Codes), phrase(longitude_degrees(Degrees), Codes).
Degrees = 178.773.

?- string_codes("-22.523", Codes), phrase(longitude_degrees(Degrees), Codes).
false.

9. 解析纬度

纬度由两部分组成:度数和半球,两者之间用一个空格分隔。实现latitude规则来解析纬度:

?- string_codes("56.101 N", Codes), phrase(latitude(Degrees, Hemisphere), Codes).
Degrees = 56.101,
Hemisphere = north.

10. 解析经度

纬度由两部分组成:度数和半球,两者之间用一个空格分隔。实现latitude规则来解析纬度:

?- string_codes("143.889 W", Codes), phrase(longitude(Degrees, Hemisphere), Codes).
Degrees = 143.889,
Hemisphere = west.

11. 解析坐标

坐标由两部分组成:纬度和经度,两者之间用一个逗号加一个空格分隔。实现coordinate规则,同时解析纬度(度数和半球):

?- string_codes("48.8584 N, 2.2945 E", Codes), phrase(coordinate(Latitude, LatitudeHemisphere, Longitude, LongitudeHemisphere), Codes).
Latitude = 48.8584,
LatitudeHemisphere = north,
Longitude = 2.2945,
LongitudeHemisphere = east.
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Prolog Exercism

准备好开始 全球定位系统 了吗?

注册 Exercism,借助 109 个练习 和真人导师指导,学习并掌握 Prolog,全部免费。