偶然看到cppblog精華區有一篇關于貌似是一道中興筆試題的代碼,文章請見
這里
個人覺得寫得不是很有美感,正好又很無聊,于是在這位的代碼基礎上改了下算法:
0、原作者可能沒有注意到他用的atoi庫函數的某些特點;
1、充分利用atoi庫函數的特性:原地可解析字符串,不必拷貝出來;
2、由于atoi這個庫函數相當于已經實現了整數的前綴匹配,只要匹配從非數字到數字那一狀態就可以了;
3、完全沒必要給臨時分配的數組初始化值,因為有index.
VS2008和DevC++下通過測試。
1
#include <iostream>
2
#include <algorithm>
3
void 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
}
25
int 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;
}