从字符串中提取数字并排序输出

从字符串中提取数字并排序输出


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



// 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) && (*!= '-' || !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 (*== ' ' || *== '\t'++p;
    
bool negative = false;
    
if (*== '-'{ negative = true++p; }
    
else if (*== '+'++p; }
        
    
int value = 0;
    
bool range_error = false;
    
bool value_read = false;
    
const char *old = p;
    
for ( ; *p; ++p) {
      
int tmp = *- '0';
      
if (tmp < 0 || tmp > 9break;
      
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 (*== 0break
    
++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 = *- '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 (*== 0break;
    
++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);
}

你可能感兴趣的:(从字符串中提取数字并排序输出)