2016-09-27 75 views
-2

所以我想採取一個字符串,如8302,並通過創建我自己的函數,而不是使用stoi/atoi函數將其轉換爲一個整數。你如何實現你自己的字符串到整數轉換

我試圖到目前爲止做:

int stringToInt(string input) 
{ 
    int i = 0; 
    while(input[i] >= '0' && input[i] <= '9') 
    { 
     input[i] = input[i] * 10 + ...... 
     i++; 
    } 
return i; 
} 

我知道我需要保持10每次乘我找到一個整數,所以我可以增加它如123 = 1 * 10 * 10 + 2 * 10 + 3。但我不知道如何編碼。任何人都可以提出一個方法

+3

你爲什麼要乘以t分別ASCII字符值他由10串? –

+3

你不應該對字符串索引和累加器使用相同的變量。爲累加器使用一個單獨的變量。 – NathanOliver

+1

而你正在返回的索引不是轉換後的數字。此外,你不檢查字符串的結尾。 –

回答

-3
void enforce(bool b) { 
    if (!b) { 
     throw std::range_error("Not a valid string to convert to integer"); 
    } 
} 

int stringToInt(std::string) { 
    for (std::size_t i(0); i != (last - first); ++i) { 
     enforce(('0' <= first[ i ]) && (first[ i ] <= '9')); 
     result += pow(10,i) * (first[ i ] - '0'); 
    } 
} 

Source

+3

'10^i'不會做你認爲它做的事。 – NathanOliver

+0

是的,忘記了@NathanOliver。感謝您指出從OP代碼 – MenaceInc

-2

這是你開始由右至左轉換好得多。

所以你會迭代你的字符串,從它的結尾開始到結束。在每次迭代中,我們將採用該字符,將其轉換爲int並將其與它的multiplier(它在結果整數中的位置)相乘,然後將其添加到最終結果中。

這應該工作:

#include <iostream> 
#include <string> 

int stringToInt(std::string input) 
{ 
    int result = 0; 
    int multiplier = 1; 

    for (int i = input.length() - 1; i >= 0; i--) // start from right 
    { 
     if (input[i] - '0' < 0 || input[i] - '0' > 9) // if any character is not an integer, return maximum negative 
     { 
      result = INT16_MIN; 
      break; 
     } 

     result += (input[i] - '0') * multiplier; // convert to int, get its position and then add it to result. 
     multiplier *= 10; // get next position 
    } 

    return result; 
} 

int main() 
{ 
    std::string MyEx = "123456"; 
    int MyInt = stringToInt(MyEx); 

    std::cout << MyInt; 

    return 0; 
} 
+1

並檢查,您不能確保所有的字符串項都是數字 –

+0

@HumamHelfawi OP沒有說明。根據他的示例輸入,不清楚其中一個字符可能不是整數。無論如何我都添加了它,並且感謝您指出它。 –

2

這可能是最簡單的做一個遞歸的方式。請使用以下的想法:

8302 = 830 * 10 + 2 

即:

  1. 如果只有一個char字符串中 - 歸還;否則繼續
  2. 獨立的最後char字符串
  3. 將字符串(沒有最後一個字符)到整數 - 使用遞歸
  4. 乘以10,並把最後char

有很多這裏的詳細信息:

  • 如何將1 char轉換爲整數? - 從中​​減去'0'
  • 如何從字符串的其餘部分中分離出char? - 使用substr
  • ,當你有一個工作的遞歸解決方案,您可能需要將其轉換爲一個迭代的解決方案 - 這將使其更快,但也許少可讀
  • 如何處理無效的字符串像"aaa""123haha"做 - 我算法不處理
+0

OP應考慮的其他問題:a。處理負數。灣如果第4步會使他的累加器溢出(如果在不觸發溢出的情況下如何檢測這些問題有一些有趣的問題),該怎麼辦。 C。結合後兩項:處理最負數的輸入而不觸發溢出。 –

+0

我認爲這些考慮主要針對未來可能會閱讀此內容的其他人; OP提到了「stoi/atoi」,所以他似乎並不關心這樣的事情,就像[atoi'不關心](http://stackoverflow.com/q/20583945/509868) – anatolyg

-1

這一個是非常接近你嘗試:

int toInt(const std::string& input) 
{ 
    int i = 0; 
    for (const auto c : input) 
    { 
    if (c < '0' || c > '9') 
     break; 
    i = i*10 + c-'0'; 
    } 
    return i; 
} 

唯一的假設是,字符'0''9'在字符集中彼此直接相鄰。 if聲明確保我們停止在非數字字符。數字字符使用c-'0'轉換爲其整數值。

請記住,這隻能解析字符串的第一個數字。不考慮以+-開頭的字符串。

+0

這是關於as乾淨,因爲它可以得到。你應該在你的答案中加上解釋,因爲它似乎最適合使用原來的答案。 – anatolyg

-1

一個好方法是找到你的第一個數字,並從那裏製作一個多人遊戲變量,並乘以十位數。每一個燒焦,添加你必須減去「0」,從爲「0」不等於0詮釋

例如:

string s = "12346"; 
int multiplayer = 1; 
int i = 0; 

int result = 0; 

while (s[i] >= '0' && s[i] <= '9') 
++i; 

--i; 
for(i ; i >= 0 ; --i){ 
    result += (s[i] - '0') * multiplayer; 
    multiplayer *= 10; 
} 
1

之前,你可以定義一個char2int轉換:

inline int ctoi(char c) { 
    switch (c) { 
    case '0': 
     return 0; 
    case '1': 
     return 1; 
    case '2': 
     return 2; 
    case '3': 
     return 3; 
    case '4': 
     return 4; 
    case '5': 
     return 5; 
    case '6': 
     return 6; 
    case '7': 
     return 7; 
    case '8': 
     return 8; 
    case '9': 
     return 9; 
    default: 
     throw std::runtime_error("Invalid char conversion"); 
    } 
} 

並使用它:

int my_stoi_dec(const std::string& str) { 
    int rtn = 0; 
    int exp = 1; 
    for (auto cp = str.crbegin(); cp != str.crend(); ++cp) { 
    char c = *cp; 
    if (isdigit(c)) { 
     rtn += ctoi(c) * exp; 
     exp *= 10; 
    } else if (c == '+') { 
     return rtn; 
    } else if (c == '-') { 
     return rtn * -1; 
    } else { 
     throw std::runtime_error("Integer error conversion"); 
    } 
    } 
} 
+0

你不應該使用幻數。這使得代碼不可移植。 – NathanOliver

+0

@NathanOliver更好? –

+0

是的。這是最完整的答案。它不處理/溢出,但我不打算爲此投票。 – NathanOliver

相關問題