你是地理寻宝的超级粉丝,这项活动把你对户外的热爱和对解谜的热爱结合在了一起。 当地的寻宝网站列出了所有藏宝点的 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)支持,它正是为解析结构化文本而设计的。
为了帮你上手,存根文件已经通过下面的代码引入了dcg/basics库:
:- use_module(library(dcg/basics)).
实现comma规则来解析单个逗号(","):
?- string_codes(",", Codes), phrase(comma, Codes).
实现space规则来解析单个空格(" "):
?- string_codes(" ", Codes), phrase(space, Codes).
修改space规则,让它解析所有空白字符,但不解析换行符:
?- string_codes("\t", Codes), phrase(space, Codes).
?- string_codes("\n", Codes), phrase(space, Codes).
false.
纬度的半球可以是"N"或"S",它们应被解析为north或south原子。实现latitude_hemisphere规则来解析纬度的半球:
?- string_codes("N", Codes), phrase(latitude_hemisphere(Hemisphere), Codes).
Hemisphere = north.
经度的半球可以是"E"或"W",它们应被解析为east或west原子。实现longitude_hemisphere规则来解析经度的半球:
?- string_codes("E", Codes), phrase(longitude_hemisphere(Hemisphere), Codes).
Hemisphere = east.
经度或纬度的度数被定义为浮点数。实现degrees规则来解析浮点数:
?- string_codes("748.012", Codes), phrase(degrees(Degrees), Codes).
Degrees = 748.012.
纬度度数不只是普通的浮点数,而是范围 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.
经度度数不只是普通的浮点数,而是范围 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.
纬度由两部分组成:度数和半球,两者之间用一个空格分隔。实现latitude规则来解析纬度:
?- string_codes("56.101 N", Codes), phrase(latitude(Degrees, Hemisphere), Codes).
Degrees = 56.101,
Hemisphere = north.
纬度由两部分组成:度数和半球,两者之间用一个空格分隔。实现latitude规则来解析纬度:
?- string_codes("143.889 W", Codes), phrase(longitude(Degrees, Hemisphere), Codes).
Degrees = 143.889,
Hemisphere = west.
坐标由两部分组成:纬度和经度,两者之间用一个逗号加一个空格分隔。实现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.