看到别人的讨论贴,也做了下。题目很简单,可以直接用标准库函数,也可以自已造轮子。标准库中能用到的只有:atoi / strtol系列,显然得用 strtol(有些库atoi就是用strtol实现的)
在用strtol前,先要对不安全的strtol封装下。
int str2i(const char str[], const char* &next, int base = 10)
{
return strtol(str, const_cast<char**>(&next), base);
}
可采用两种算法:
1 先忽略空白字符,然后直接调用str2i (代码 solve1)
2 先找到合法数字的第一个字符,再调用str2i(代码 solve2)
当然也可以自行实现strtol(代码: solve3和solve4)。
// http://cnblogs.com/flyinghearts
#include <iostream>
#include <algorithm>
#include <iterator>
#include <deque>
#include <limits>
#include <cstdlib>
using std::cout;
int str2i(const char str[], const char* &next, int base = 10)
{
return strtol(str, const_cast<char**>(&next), base);
}
void solve1(const char* str)
{
if (str == NULL) return;
std::deque<int> dq;
const char* p = str;
const char* next = NULL;
while (*p) {
if (isspace(*p)) {
++p;
continue;
}
errno = 0;
int value = str2i(p, next);
if (errno != 0) {
cout << "data error at pos: " << p - str << "\n";
p = next;
continue;
}
if (next > p) {
p = next;
dq.push_back(value);
continue;
}
++p;
}
std::sort(dq.begin(), dq.end());
std::copy(dq.begin(), dq.end(), std::ostream_iterator<int>(cout," "));
cout << "\n\n";
}
void solve2(const char* str)
{
if (str == NULL) return;
std::deque<int> dq;
const char* p = str;
const char* next = NULL;
while (*p) {
if (!isdigit(*p) && (*p != '-' || !isdigit(*(p + 1)))) {
++p;
continue;
}
errno = 0;
int value = str2i(p, next);
if (errno != 0) {
cout << "data error at pos: " << p - str << "\n";
p = next;
continue;
}
if (next > p) {
p = next;
dq.push_back(value);
}
}
std::sort(dq.begin(), dq.end());
std::copy(dq.begin(), dq.end(), std::ostream_iterator<int>(std::cout," "));
cout << "\n\n";
}
void solve3(const char* str)
{
//const int max_int = -1u / 2u;
const int max_int = std::numeric_limits<int>::max();
const int max_value = max_int / 10;
const int value_left = max_int % 10;
const char* p = str;
std::deque<int> dq;
while (*p) {
while (*p == ' ' || *p == '\t') ++p;
bool negative = false;
if (*p == '-') { negative = true; ++p; }
else if (*p == '+') { ++p; }
int value = 0;
bool range_error = false;
bool value_read = false;
const char *old = p;
for ( ; *p; ++p) {
int tmp = *p - '0';
if (tmp < 0 || tmp > 9) break;
if (range_error) continue;
if (value > max_value || (value == max_value && tmp > value_left + negative)) {
range_error = true;
continue;
}
value = value * 10 + tmp;
value_read = true;
}
if (range_error) {
cout << "data error at pos: " << old - str << "\n";
continue;
}
if (value_read) {
if (negative) value = - value;
dq.push_back(value);
}
if (*p == 0) break;
++p;
}
std::sort(dq.begin(), dq.end());
std::copy(dq.begin(), dq.end(), std::ostream_iterator<int>(std::cout," "));
cout << "\n\n";
}
void solve4(const char* str)
{
//const int max_int = -1u / 2u;
const int max_int = std::numeric_limits<int>::max();
const int max_value = max_int / 10;
const int value_left = max_int % 10;
const char* p = str;
std::deque<int> dq;
bool negative = false;
while (*p) {
if (!isdigit(*p)) {
if (*p++ != '-' ) continue;
if (!isdigit(*p)) continue;
negative = true;
}
const char *old = p;
int value = *p++ - '0';
bool range_error = false;
for ( ; *p; ++p) {
if (!isdigit(*p)) break;
if (range_error) continue;
int tmp = *p - '0';
if (value > max_value || (value == max_value && tmp > value_left + negative)) {
range_error = true;
continue;
}
value = value * 10 + tmp;
}
if (range_error) {
cout << "data error at pos: " << old - str << "\n";
continue;
}
if (negative) {
value = - value;
negative = false;
}
dq.push_back(value);
if (*p == 0) break;
++p;
}
std::sort(dq.begin(), dq.end());
std::copy(dq.begin(), dq.end(), std::ostream_iterator<int>(std::cout," "));
cout << "\n\n";
}
int main()
{
char ss[] = "2147483646 2147483647 2147483648 -2147483647 -2147483648 -2147483649";
char str[] = "-a33k&-99+r5s-w1f10g-2d4vc+511m99999999999999gc3-";
solve1(str);
solve2(str);
solve3(str);
solve4(str);
solve1(ss);
solve2(ss);
solve3(ss);
solve4(ss);
}