Lintcode 529. Geohash
Geohash is a hash function that convert a location coordinate pair into a base32 string.
Check how to generate geohash on wiki: Geohash or just google it for more details.
Try http://geohash.co/.
You task is converting a (latitude, longitude) pair into a geohash string.
Example
Example1
Input:
lat = 39.92816697
lng = 116.38954991
precision = 12
Output: “wx4g0s8q3jf9”
Example2
Input:
lat = -90
lng = 180
precision = 12
Output: “pbpbpbpbpbpb”
Notice
1 <= precision <=12
解法1:
这题就是Geohash II的逆运算。
需要注意的是
1) totalCode必须用string, 不能long long,否则肯定溢出。
class GeoHash {
public:
/*
* @param latitude: one of a location coordinate pair
* @param longitude: one of a location coordinate pair
* @param precision: an integer between 1 to 12
* @return: a base32 string
*/
string encode(double latitude, double longitude, int precision) {
string base32Map = "0123456789bcdefghjkmnpqrstuvwxyz";
vector<double> longitudeRange = {-180, 180};
vector<double> latitudeRange = {-90, 90};
// long long value = 0; it is wrong to use long long, will over flow. Should use string.
string totalCode;
string result;
int len = 5 * precision - 1;
while (len >= 0) {
double longitudeMid = (longitudeRange[0] + longitudeRange[1]) / 2;
double latitudeMid = (latitudeRange[0] + latitudeRange[1]) / 2;
if (longitude > longitudeMid) {
totalCode = totalCode + '1';
longitudeRange[0] = longitudeMid;
} else {
totalCode = totalCode + '0';
longitudeRange[1] = longitudeMid;
}
if (latitude > latitudeMid) {
totalCode = totalCode + '1';
latitudeRange[0] = latitudeMid;
} else {
totalCode = totalCode + '0';
latitudeRange[1] = latitudeMid;
}
len -=2;
}
for (int i = 0; i < precision; ++i) {
string subCode = totalCode.substr(i * 5, 5);
result = result + base32Map[mapping(subCode)];
}
return result;
}
private:
// mapping a 5-digit bin to the index, like atoi
int mapping(string code) {
int result = 0;
int len = code.size();
for (int i = 0; i < len; ++i) {
if (code[i] == '1') {
result += 1 << (len - i - 1);
}
}
return result;
}
};