數字 int 轉字串和字串轉數字 int

2022-07-09 20:12:13 字數 3346 閱讀 1602

室友去面試,問了乙個字串轉成數字的演算法題,室友沒搞出來,我心想,這個不是很簡單的嗎?於是動手在紙上畫了畫**。畫完後,總感覺**不對,最後乙個個挖掘,才發現,尼瑪,這到處都是坑啊~~~特此記錄一下中坑心路。

首先看一下數字轉成字串。輸入乙個整型數字,寫乙個函式,返回整型數字對應的字串形式。如:

輸入:345

輸出:"345"

這個問題第一思路應該是:對整型數字每次求最高位數字,如3,將其轉換為對應字元 '3' ,然後將此整型值取下面的數,直到整型值為0,輸出字串。這個問題是,怎麼求最高位的數字,可以用乙個迴圈將number累除10,直到number小於10,即為最高位。解法如下:

char * int2str(int nb)else if(0==nb)

int tmpnum,len;

while(nb!=0)

str[nindex++]=tmpnum+'0';

nb=nb-tmpnum*len; //nb 減去最高位

if(nb==0)

}str[nindex]='\0'; //新增結束符號

return str;

}

在**a中考慮了所有可能出現的情況,如:整數nb為0或負數時的情況,整數nb的最後一位為0時的情況(僅限此種思路的情況)。可以看到,演算法主要的計算部分在兩個while迴圈中,假設nb共有m位。則第乙個迴圈需要迴圈m次,第二個迴圈總迴圈次數為:\((m-1)+(m-2)+...+3+2+1=m(m-1)/2\) ,總共的迴圈次數為\((m-1)m/2\),時間複雜度為:\(o(m^2)\)。當然,由於整型數字,最長才只有10位(不包含正負號),所以常數時間內即可解決。但有沒有其他解法了呢?

如果我們從低位開始轉換進字元陣列裡,而不是從高位開始,那不就能省掉第二個while迴圈了嘛!問題是,我們一開始並不知道整數nb有多少位!所以我們轉換的低位放到字元陣列str的**呢?這裡有兩種思路:

char * int2strb(int nb)else if(0==nb)

unsigned int len=0; //記錄nb的位數

int tmpnb=nb;

while(0!=tmpnb)

if(nindex==0)--len; //在str中定位最後一位數字應該在的位置

str[len+1]='\0'; //設定結束符號

while(0!=nb)

return str;

}

**b中,首先乙個迴圈求出整數nb(如果nb為負數,此時已經轉換為對應的正數)總共位數m,需要迴圈m次,時間複雜度為\(o(m)\);第二個迴圈依然是依次遍歷整數nb的每一位,時間複雜度依然為\(o(m)\),所以總時間複雜度為:\(o(m)+o(m)=o(m)\)。當然,其實m是有最大數限制的。

char * int2strc(int nb)else if(0==nb)

unsigned int nstar=nindex; //記錄要逆序的初始位置

while(0!=nb)

str[nindex]='\0';

//字串逆序

--nindex;

while(nstar**c中也有兩個迴圈,第乙個迴圈完成將整數nb從低位到高位逆序轉換進str中,需要時間複雜度為\(o(m)\);第二個迴圈將對應數字的部分進行逆序,時間複雜度為\(o(m/2)=o(m)\),所以總時間複雜度也為:\(o(m)\)。

至於b和c哪個更好,我是建議用b的,簡潔明瞭。至於誰更快寫,肯定都比a快,其次由於m是一常數,自然(m+m)>(m+m/2)的,但是在c中比b中的迴圈多出三條賦值操作,因為m不會大於11,所以,這個誰更好,就難說了~~(不知道這個分析的是否有問題~~~)

這個其實就是實現一下c庫函式的atoi函式。當然我們有個簡單的處理,就是使用c++的stringstream類,**如下:

#include typedef long long dlong;

enum status;

int g_status=kvalid; //合法輸入

int str2inta(const char* str)

stringstream stream(str);

dlong num=int_max+10; //大於整型最大數,判斷溢位

stream>>num;

if(num>int_max || num**d中,首先我們要處理的乙個問題就是,當輸入的字串非法時,返回什麼?返回0嗎?但返回0怎麼區分這個0不是合法輸入返回的呢,所以要引入乙個全域性變數,當輸入非法的時候將全域性變數置為非法,否則置為合法。注釋中已經說明了可能的非法輸入情況,這裡就不在多說。但是stringstream流也能將下面的輸入正確輸出:

輸入: "234dsdf"

輸出:234

而我們知道,這其實輸入乙個非法的輸入。當然我們可以更改**進行遍歷去判斷這個,但其實如果在面試中,我覺得考官應該不是希望我們使用這個庫函式的。而應該是去重新實現c版本的那個atoi函式。所以上**e:

typedef long long dlong;

enum status;

int g_status=kvalid; //合法輸入

int str2intb(const char* str){

g_status=kinvalid;

if(str==nullptr || *str=='\0')return 0; //指標不為空,字串不為空

char const* pstr=str;

int flag=1; //判斷正負數,預設為正數

dlong num=0; //防溢位

if(*pstr=='-')flag=-1; //負數

else if(*pstr=='+') flag=1; //正數

else if(*pstr<'0' && *pstr>'9')return 0;//非法輸入

else num=(*pstr-'0')*flag; //上來就是數字,為正數

++pstr;

if(*pstr!='\0'){ //防止字串為"+",或 "-"的情況

while(*pstr!='\0'){ //迴圈求數字

if(*pstr>='0' && *pstr<='9'){

num=num*10+(*pstr-'0')*flag;

if((flag==1 && num>int_max) ||

(flag==-1 && num至於思路,就是先去除非法輸入部分,然後乙個數字乙個數字的轉換為對應字元。注釋裡說的都已經很清楚了,所以就不多說了。

數字轉字串 字串轉數字

數字轉字串 這裡首先用到乙個陣列逆置函式如下 void reverse char arr 逆置 for p arr p arr p 將arr陣列逆置 因為將乙個數字轉成字串,若果是從右往左依次獲得,操作較容易,所以以此得到的字串是數字的逆序字串,所以要逆置,才可得到順序 如下 void myitoa...

c 字串轉數字或數字轉字串

在c 中字串轉換為數字,或數字轉換為字串,用到如下函式 itoa atoi atof itoa itow itoa s 1.整形轉換為字串 2.字串轉為整形 在字符集設定不同下會有不同的型別,說白了,這幾個函式的功能都相同,但是根據你的字符集不同,選用的函式也不同。itot 在asicii下被巨集定...

字串 字串轉數字

題目 將乙個字串轉換成數字。例如 123 123,71.02 71.02.方法一,直接呼叫庫函式atoi const char 和atof const char stoi string str include include int main 輸出結果 num int 435 num double ...