这是 Naveen 和 Don 算法的实现。它使用 Happy Yellow Face 的算法作为测试预言机。
我很高兴看到人们对其进行调整以删除多余的步骤或特殊情况。
gcc 4.7.3:g++ -Wall -Wextra -std=c++0x 最近回文.cpp
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
// I do not have std::to_string.
template <class T>
std::string to_string(const T& v) {
std::stringstream ss;
ss << v;
return ss.str(); }
// Nor do I have std::stoi. :(
int stoi(const std::string& s) {
std::stringstream ss(s);
int v;
ss >> v;
return v; }
bool isPalindrome(int n) {
const auto s = to_string(n);
return s == std::string(s.rbegin(), s.rend()); }
int specNearestPalindrome(int n) {
assert(0 <= n);
int less = n, more = n;
while (true) {
if (isPalindrome(less)) { return less; }
if (isPalindrome(more)) { return more; }
--less; ++more; } }
std::string reflect(std::string& str, int n) {
std::string s(str);
s.resize(s.size() + n);
std::reverse_copy(std::begin(str),
std::next(std::begin(str), n),
std::next(std::begin(s), str.size()));
return s; }
bool isPow10(int n) {
return n < 10 ? n == 1 : (n % 10 == 0) && isPow10(n / 10); }
int nearestPalindrome(int n) {
assert(0 <= n);
if (n != 1 && isPow10(n)) { return n - 1; } // special case
auto nstr = to_string(n);
// first half, rounding up
auto f1 = nstr.substr(0, (nstr.size() + 1) / 2);
auto p1 = stoi(reflect(f1, nstr.size() / 2));
const auto twiddle = p1 <= n ? 1 : -1;
auto f2 = to_string((stoi(f1) + twiddle));
auto p2 = stoi(reflect(f2, nstr.size() / 2));
if (p2 < p1) { std::swap(p1, p2); }
return n - p1 <= p2 - n ? p1 : p2; }
int main() {
std::vector<int> tests = { 0, 1, 6, 9, 10, 11, 12, 71, 74, 79, 99, 100, 999, 1000, 9900, 9999, 999000 };
for (const auto& t : tests) {
std::cout <<
(nearestPalindrome(t) == specNearestPalindrome(t) ? "." : "X");
}
std::cout << std::endl;
return 0; }