偶然看到cppblog精华区有一篇关于貌似是一道中兴笔试题的代码,文章请见这里
个人觉得写得不是很有美感,正好又很无聊,于是在这位的代码基础上改了下算法:

0、原作者可能没有注意到他用的atoi库函数的某些特点;
1、充分利用atoi库函数的特性:原地可解析字符串,不必拷贝出来;
2、由于atoi这个库函数相当于已经实现了整数的前缀匹配,只要匹配从非数字到数字那一状态就可以了;
3、完全没必要给临时分配的数组初始化值,因为有index.

VS2008和DevC++下通过测试。


 1#include <iostream>
 2#include <algorithm>
 3void output(char* str,int len)
 4{  
 5   if(str==NULL||len<= 0)
 6       return
 7
 8   int * numList=new int[len],index=0,i;   
 9   char * isDigit=new char[len];//isDigit[i]存储着:str[i]是否为数字
10   for(i=0;(i!=len) 
11       &&(isDigit[i]=(str[i]<='9'&&str[i]>='0'),1);i++);//建立isDigit数组目的是避免重复运算
12
13   if(isDigit[0]!=0)//避免取到isDigit[-1]
14       numList[index++]=atoi(str);
15   for(i=1;i!=len;i++)
16       if(isDigit[i-1]==0&&isDigit[i]!=0)//若是从上一个非数字字符跳到现在的数字字符,则从此处转换一次整数到numList列表 
17           numList[index++]=atoi(str+i);
18
19   std::sort(numList,numList+index);//排序
20   std::copy(numList,numList+index,
21       std::ostream_iterator<int>(std::cout," "));
22   delete [] numList;   
23   delete [] isDigit;
24}

25int main()
26{   
27    char input[] = "33k&99+r5sw1f10gd4vc511gc3";
28    output(input,strlen(input));
29    return 0;
30}



为了榨取性能和空间,我进一步改得略微丑陋了些,但某些地方改得更美观- -bnr:


#include <iostream>
#include 
<algorithm>
void output(char* str,int len)
{  
   
if(str==NULL||len<= 0)
       
return
   
int * numList=new int[len],index=0,i;
   
bool * isDigit=new bool[len];//isDigit[i]存储着:str[i]是否为数字
   for(i=0;i != len;i++)//建立isDigit数组目的是避免重复运算
      isDigit[i] = str[i]<='9'&&str[i]>='0';

   
if(*isDigit++ != 0)//避免取到isDigit[-1]
      numList[index++= atoi(str++);
   
for(;*str !=0 ;++str,++isDigit)
       
if(!*(isDigit-1)&& *(isDigit))//若是从上一个非数字字符跳到现在的数字字符,则从此处转换一次整数到numList列表 
           numList[index++= atoi(str);

   std::sort( numList , numList
+index);//排序
   for(i=0;i != index;++i)
       std::cout
<<numList[i]<<" ";
   delete [] numList;   
   delete [] (isDigit
-len);
}

int main()
{   
    
char input[] = "33k&99+r5sw1f10gd4vc511gc3";
    output(input,strlen(input));
    
return 0;
}