看到别人的讨论贴,也做了下。题目很简单,可以直接用标准库函数,也可以自已造轮子。标准库中能用到的只有: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);
}