Skip to content

Commit efd1bd6

Browse files
authored
Merge pull request #10 from rihib/string_to_integer_atoi
String to Integer (atoi)
2 parents 5595670 + 0e147d1 commit efd1bd6

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package stringtointegeratoi
3+
4+
import "math"
5+
6+
/*
7+
時間:20分
8+
解法自体はすぐに思いついたのですが、色々とバグを取り除くのに時間がかかってしまいました。
9+
*/
10+
func myAtoi_step1(s string) int {
11+
const (
12+
intMax = int(math.MaxInt32)
13+
intMin = int(math.MinInt32)
14+
)
15+
sign := 1
16+
i := 0
17+
num := 0
18+
for i < len(s) && s[i] == ' ' {
19+
i++
20+
}
21+
if i < len(s) && (s[i] == '-' || s[i] == '+') {
22+
if s[i] == '-' {
23+
sign = -1
24+
}
25+
i++
26+
}
27+
for i < len(s) && s[i] == '0' {
28+
i++
29+
}
30+
for i < len(s) && '0' <= rune(s[i]) && rune(s[i]) <= '9' {
31+
num = num*10 + int(rune(s[i])-'0')
32+
if sign == 1 && num > intMax {
33+
return intMax
34+
}
35+
if sign == -1 && -num < intMin {
36+
return intMin
37+
}
38+
i++
39+
}
40+
return num * sign
41+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package stringtointegeratoi
3+
4+
import "math"
5+
6+
/*
7+
Goではrune型はint32、byte型はint8のエイリアスで、明示的にキャストしなくても内部でキャストしてくれるので、そのまま比較できるため、rune型にキャストするのをやめました。
8+
*/
9+
func myAtoi_step2(s string) int {
10+
const (
11+
intMax = int(math.MaxInt32)
12+
intMin = int(math.MinInt32)
13+
)
14+
15+
i := 0
16+
for i < len(s) && s[i] == ' ' {
17+
i++
18+
}
19+
20+
sign := 1
21+
if i < len(s) && (s[i] == '-' || s[i] == '+') {
22+
if s[i] == '-' {
23+
sign = -1
24+
}
25+
i++
26+
}
27+
28+
num := 0
29+
for i < len(s) && '0' <= s[i] && s[i] <= '9' {
30+
num = num*10 + int(s[i]-'0')
31+
if sign == 1 && num > intMax {
32+
return intMax
33+
}
34+
if sign == -1 && -num < intMin {
35+
return intMin
36+
}
37+
i++
38+
}
39+
return sign * num
40+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package stringtointegeratoi
3+
4+
import "math"
5+
6+
/*
7+
32bit環境でもオーバーフローしないようにコードを変えてみました。
8+
*/
9+
func myAtoi(s string) int {
10+
const (
11+
intMax = int(math.MaxInt32)
12+
intMin = int(math.MinInt32)
13+
)
14+
15+
i := 0
16+
for i < len(s) && s[i] == ' ' {
17+
i++
18+
}
19+
20+
sign := 1
21+
if i < len(s) && (s[i] == '-' || s[i] == '+') {
22+
if s[i] == '-' {
23+
sign = -1
24+
}
25+
i++
26+
}
27+
28+
num := 0
29+
for i < len(s) && '0' <= s[i] && s[i] <= '9' {
30+
next := int(s[i] - '0')
31+
if sign != -1 && num > (intMax-next)/10 {
32+
return intMax
33+
}
34+
if sign == -1 && -num < (intMin+next)/10 {
35+
return intMin
36+
}
37+
num = num*10 + next
38+
i++
39+
}
40+
return sign * num
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package stringtointegeratoi
3+
4+
import "math"
5+
6+
/*
7+
Step3のオーバーフローしてしまうバグを直しました。
8+
*/
9+
func myAtoi_step4(s string) int {
10+
const (
11+
intMax = int(math.MaxInt32)
12+
intMin = int(math.MinInt32)
13+
)
14+
15+
i := 0
16+
for i < len(s) && s[i] == ' ' {
17+
i++
18+
}
19+
20+
sign := 1
21+
if i < len(s) && (s[i] == '-' || s[i] == '+') {
22+
if s[i] == '-' {
23+
sign = -1
24+
}
25+
i++
26+
}
27+
28+
num := 0
29+
for i < len(s) && '0' <= s[i] && s[i] <= '9' {
30+
digit := int(s[i] - '0')
31+
if sign == 1 && (num > intMax/10 || num == intMax/10 && digit >= intMax%10) {
32+
return intMax
33+
}
34+
if sign == -1 && (-num < intMin/10 || -num == intMin/10 && -digit <= intMin%10) {
35+
return intMin
36+
}
37+
num = num*10 + digit
38+
i++
39+
}
40+
return sign * num
41+
}

0 commit comments

Comments
 (0)