Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions Algorithm/Other/leetcode/atoi/8. String to Integer (atoi)/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
TypeScriptでの `myAtoi` 実装における**各処理ステップを図解**付きで詳細に解説します。例として、入力文字列が `" -042abc"` の場合を扱います。

---

## ✅ ステップ1: 空白のスキップ

```typescript
while (i < n && s[i] === ' ') {
i++;
}
```

### 🔍 処理前

```
s = " -042abc"
i=0
```

空白をスキップしていく:

```
s = " -042abc"
i=3
```

➡ `i = 3` で空白スキップ完了。`s[3] = '-'`

---

## ✅ ステップ2: 符号の確認

```typescript
if (i < n && (s[i] === '+' || s[i] === '-')) {
if (s[i] === '-') sign = -1;
i++;
}
```

### 🔍 処理前

```
s = " -042abc"
i=3, s[i]='-'
```

* `'-'` を発見 → `sign = -1`
* `i++`

### 🔍 処理後

```
s = " -042abc"
i=4, s[i]='0'
sign = -1
```

---

## ✅ ステップ3: 数字部分の読み取り

```typescript
while (i < n && s[i] >= '0' && s[i] <= '9') {
const digit = s[i].charCodeAt(0) - '0'.charCodeAt(0);
result = result * 10 + digit;
i++;
}
```

### 🧮 処理ステップ(ループ)

#### 1周目(s\[4] = '0')

```
digit = 0
result = 0 * 10 + 0 = 0
i → 5
```

#### 2周目(s\[5] = '4')

```
digit = 4
result = 0 * 10 + 4 = 4
i → 6
```

#### 3周目(s\[6] = '2')

```
digit = 2
result = 4 * 10 + 2 = 42
i → 7
```

#### 4周目(s\[7] = 'a')

* `s[7]` は数字でないため **ループ終了**

### 🔍 終了時

```
result = 42
sign = -1
```

---

## ✅ ステップ4: オーバーフローの処理と返却

```typescript
return result * sign;
```

```
result = 42
sign = -1
→ return -42
```

---

## ✅ 最終結果

```
入力: " -042abc"
出力: -42
```

---

## 🧠 全体のフローチャート風まとめ

```
入力: " -042abc"

↓ ステップ1: 空白スキップ
i = 0 → 3

↓ ステップ2: 符号チェック
s[3] = '-' → sign = -1, i = 4

↓ ステップ3: 数字読み取り
s[4] = '0' → result = 0
s[5] = '4' → result = 4
s[6] = '2' → result = 42
s[7] = 'a' → 終了

↓ ステップ4: 結果に符号適用
-1 × 42 = -42

→ ✅ 出力: -42
```

---

## ✅ 他の例も図で簡潔に

### 例1: `"words and 987"`

```
s = "words and 987"
s[0] = 'w'(非数字)→ 数字読み取り前に終了 → return 0
```

---

### 例2: `"91283472332"`(オーバーフロー)

```
result = 91283472332 > INT_MAX
→ return INT_MAX = 2147483647
```

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 以下は、指定された仕様に従って `myAtoi` 関数を TypeScript で実装したものです。
function myAtoi(s: string): number {
const INT_MIN = -(2 ** 31);
const INT_MAX = 2 ** 31 - 1;

let i = 0;
const n = s.length;

// 1. 空白をスキップ
while (i < n && s[i] === ' ') {
i++;
}

// 2. 符号の確認
let sign = 1;
if (i < n && (s[i] === '+' || s[i] === '-')) {
if (s[i] === '-') sign = -1;
i++;
}

// 3. 数字を読み取る
let result = 0;
while (i < n && s[i] >= '0' && s[i] <= '9') {
const digit = s[i].charCodeAt(0) - '0'.charCodeAt(0);

// 4. オーバーフロー確認
if (result > Math.floor(INT_MAX / 10) ||
(result === Math.floor(INT_MAX / 10) && digit > INT_MAX % 10)) {
return sign === 1 ? INT_MAX : INT_MIN;
}

result = result * 10 + digit;
i++;
}

return result * sign;
}

// ### ✅ 処理フローの図解説明

// #### 例: `" -042"` の場合

// | ステップ | 処理 | 状態 |
// | ---- | ------------------------ | ------------------ |
// | 1 | 空白をスキップ (`i=0→3`) | `i=3`, `s[i]='-'` |
// | 2 | `'-'`を見つけた → `sign = -1` | `i=4`, `sign = -1` |
// | 3 | `0` → `4` → `2` と読み取る | `result = 42` |
// | 4 | 範囲内 → そのまま返す | `return -42` |

// ---

// ### ✅ 制約への対応

// * 空文字列や非数字始まり → `0` を返す
// * 数値部分が 32-bit の範囲外 → オーバーフロー対策済み
// * 入力が `"words and 987"` のようなケース → 先頭が非数字 → `0` を返す

// ---

// ### ✅ テスト例

// ```typescript
// console.log(myAtoi("42")); // 42
// console.log(myAtoi(" -042")); // -42
// console.log(myAtoi("1337c0d3")); // 1337
// console.log(myAtoi("0-1")); // 0
// console.log(myAtoi("words and 987")); // 0
// console.log(myAtoi("-91283472332")); // -2147483648(下限に丸められる)
// console.log(myAtoi("91283472332")); // 2147483647(上限に丸められる)
// ```
117 changes: 117 additions & 0 deletions Mathematics/Prefix Sum/atcoder/B06/B06.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// ### 🔍 よくあるランタイムエラーの原因(Go)

// | 原因 | 内容 |
// | ---------------- | ------------------------------------------------------- |
// | ❌ インデックスエラー | `acc[L-1]` のように `L=1` のとき `acc[0]` にアクセスできない or スライス外参照 |
// | ❌ スキャン不足 | 入力のスキャン回数が `Q` に足りていない(クエリが途中で終わる) |
// | ❌ スペースのない入力の処理ミス | `bufio.Scanner` が 1行ずつ読み取る前提で、改行の無い入力に対応できていない |
// | ❌ 空文字列の変換 | `strconv.Atoi("")` のように、空の文字列を数値に変換してエラー |

// ### ✅ 修正版 Go コード(安全対策込み)

package main

import (
"bufio"
"os"
"strconv"
"strings"
)

func main() {
reader := bufio.NewReader(os.Stdin)

// Read N
line, _ := reader.ReadString('\n')
N, _ := strconv.Atoi(strings.TrimSpace(line))

// Read A
line, _ = reader.ReadString('\n')
Astr := strings.Fields(line)
A := make([]int, N+1) // 1-indexed
for i := 1; i <= N; i++ {
A[i], _ = strconv.Atoi(Astr[i-1])
}

// Build prefix sum
acc := make([]int, N+1)
for i := 1; i <= N; i++ {
acc[i] = acc[i-1] + A[i]
}

// Read Q
line, _ = reader.ReadString('\n')
Q, _ := strconv.Atoi(strings.TrimSpace(line))

writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()

// Read and process queries
for i := 0; i < Q; i++ {
line, err := reader.ReadString('\n')
if err != nil {
break // 安全策
}
LR := strings.Fields(line)
if len(LR) < 2 {
continue // 不正入力回避
}
L, _ := strconv.Atoi(LR[0])
R, _ := strconv.Atoi(LR[1])

if L < 1 || R > N || L > R {
writer.WriteString("draw\n") // 安全なフォールバック
continue
}

ones := acc[R] - acc[L-1]
total := R - L + 1
zeros := total - ones

if ones > zeros {
writer.WriteString("win\n")
} else if zeros > ones {
writer.WriteString("lose\n")
} else {
writer.WriteString("draw\n")
}
}
}

// ## ✅ 修正ポイントまとめ

// | 修正箇所 | 説明 | | |
// | --------------------------- | ----------------------- | - | ----------------------- |
// | ✅ `bufio.NewReader` 使用 | `bufio.Scanner` の行制限を回避 | | |
// | ✅ `strings.Fields` 使用 | 空白区切り入力を安全に処理 | | |
// | ✅ `acc` と `A` を 1-indexed に | `acc[L-1]` アクセスを安全にするため | | |
// | ✅ クエリ境界チェック | \`L < 1 | | R > N\` などの入力ミスで落ちないように |

// ---

// ## ✅ 確認テスト(例)

// ### 入力

// ```
// 7
// 0 1 1 0 1 0 0
// 3
// 2 5
// 2 7
// 5 7
// ```

// ### 出力

// ```
// win
// draw
// lose
// ```

// ## ✅ 補足

// * 万が一、`LR` の長さが不足する場合(不完全な入力など)にも対応。
// * クエリ数が `Q` 未満でもクラッシュしないように `err != nil` チェック。

Loading