Skip to content

Commit faf6c1c

Browse files
committed
feat: 添加可拖拽进度条、算法思路面板和README
1 parent babb79a commit faf6c1c

19 files changed

+1166
-66
lines changed
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
# Design Document
2+
3+
## Overview
4+
5+
算法解释增强系统旨在为全排列可视化工具添加更深入的算法概念展示功能。参考 LeetCode 题解的讲解方式,通过 Used 数组可视化、递归调用栈展示、"选择-探索-撤销"模式高亮、伪代码同步等功能,帮助用户深入理解回溯算法的执行原理。
6+
7+
核心功能包括:
8+
- Used 数组状态可视化
9+
- 递归调用栈实时展示
10+
- 回溯三阶段模式高亮
11+
- 伪代码同步高亮
12+
- 剪枝原因提示
13+
14+
## Architecture
15+
16+
```mermaid
17+
graph TB
18+
subgraph UI Layer
19+
App[App Component]
20+
UsedArrayPanel[UsedArrayPanel]
21+
RecursionStackPanel[RecursionStackPanel]
22+
PhaseIndicator[PhaseIndicator]
23+
PseudocodePanel[PseudocodePanel]
24+
TreeVisualization[TreeVisualization Enhanced]
25+
end
26+
27+
subgraph Logic Layer
28+
AlgorithmStateEngine[AlgorithmStateEngine]
29+
UsedArrayTracker[UsedArrayTracker]
30+
StackFrameBuilder[StackFrameBuilder]
31+
PseudocodeMapper[PseudocodeMapper]
32+
end
33+
34+
subgraph State Management
35+
AppState[React State]
36+
end
37+
38+
App --> UsedArrayPanel
39+
App --> RecursionStackPanel
40+
App --> PhaseIndicator
41+
App --> PseudocodePanel
42+
App --> TreeVisualization
43+
44+
AlgorithmStateEngine --> UsedArrayTracker
45+
AlgorithmStateEngine --> StackFrameBuilder
46+
AlgorithmStateEngine --> PseudocodeMapper
47+
48+
UsedArrayTracker --> AppState
49+
StackFrameBuilder --> AppState
50+
PseudocodeMapper --> AppState
51+
52+
AppState --> UsedArrayPanel
53+
AppState --> RecursionStackPanel
54+
AppState --> PhaseIndicator
55+
AppState --> PseudocodePanel
56+
```
57+
58+
## Components and Interfaces
59+
60+
### Used Array Tracker
61+
62+
```typescript
63+
// Used 数组状态
64+
interface UsedArrayState {
65+
numbers: number[]; // 原始输入数组
66+
used: boolean[]; // 每个数字的使用状态
67+
lastChangedIndex: number | null; // 最近变化的索引(用于动画)
68+
changeType: 'select' | 'backtrack' | null; // 变化类型
69+
}
70+
71+
// Used 数组追踪器
72+
interface IUsedArrayTracker {
73+
getUsedArray(inputNumbers: number[], currentPath: number[]): UsedArrayState;
74+
getChangedIndex(prevPath: number[], currentPath: number[], inputNumbers: number[]): number | null;
75+
}
76+
```
77+
78+
### Recursion Stack
79+
80+
```typescript
81+
// 栈帧结构
82+
interface StackFrame {
83+
depth: number; // 递归深度(从0开始)
84+
path: number[]; // 当前路径
85+
available: number[]; // 可选数字
86+
currentChoice: number | null; // 当前选择的数字
87+
}
88+
89+
// 递归栈状态
90+
interface RecursionStackState {
91+
frames: StackFrame[];
92+
maxDepth: number;
93+
}
94+
95+
// 栈帧构建器
96+
interface IStackFrameBuilder {
97+
buildStack(currentPath: number[], available: number[], inputNumbers: number[]): RecursionStackState;
98+
}
99+
```
100+
101+
### Phase Indicator
102+
103+
```typescript
104+
// 回溯阶段
105+
type BacktrackPhase = 'choose' | 'explore' | 'unchoose' | 'complete' | 'idle';
106+
107+
// 阶段指示器状态
108+
interface PhaseIndicatorState {
109+
phase: BacktrackPhase;
110+
targetNumber: number | null; // 选择或撤销的数字
111+
description: string; // 阶段描述
112+
}
113+
114+
// 阶段颜色映射
115+
const PHASE_COLORS: Record<BacktrackPhase, string> = {
116+
choose: '#4CAF50', // 绿色 - 选择
117+
explore: '#2196F3', // 蓝色 - 探索
118+
unchoose: '#FF9800', // 橙色 - 撤销
119+
complete: '#9C27B0', // 紫色 - 完成
120+
idle: '#9E9E9E' // 灰色 - 空闲
121+
};
122+
```
123+
124+
### Pseudocode Mapper
125+
126+
```typescript
127+
// 伪代码行
128+
interface PseudocodeLine {
129+
lineNumber: number;
130+
code: string;
131+
indent: number;
132+
type: 'function' | 'condition' | 'action' | 'recursion' | 'return';
133+
}
134+
135+
// 伪代码状态
136+
interface PseudocodeState {
137+
lines: PseudocodeLine[];
138+
highlightedLine: number | null;
139+
highlightType: 'select' | 'backtrack' | 'complete' | 'recursion' | null;
140+
}
141+
142+
// 伪代码映射器
143+
interface IPseudocodeMapper {
144+
getHighlightedLine(stepType: StepType): number;
145+
getPseudocode(): PseudocodeLine[];
146+
}
147+
148+
// 回溯算法伪代码
149+
const BACKTRACK_PSEUDOCODE: PseudocodeLine[] = [
150+
{ lineNumber: 1, code: 'function backtrack(path, used):', indent: 0, type: 'function' },
151+
{ lineNumber: 2, code: ' if path.length == n:', indent: 1, type: 'condition' },
152+
{ lineNumber: 3, code: ' result.add(path.copy()) // 添加结果', indent: 2, type: 'action' },
153+
{ lineNumber: 4, code: ' return', indent: 2, type: 'return' },
154+
{ lineNumber: 5, code: ' for i in range(n):', indent: 1, type: 'condition' },
155+
{ lineNumber: 6, code: ' if used[i]: continue // 剪枝', indent: 2, type: 'condition' },
156+
{ lineNumber: 7, code: ' path.append(nums[i]) // 选择', indent: 2, type: 'action' },
157+
{ lineNumber: 8, code: ' used[i] = true', indent: 2, type: 'action' },
158+
{ lineNumber: 9, code: ' backtrack(path, used) // 递归', indent: 2, type: 'recursion' },
159+
{ lineNumber: 10, code: ' path.pop() // 撤销选择', indent: 2, type: 'action' },
160+
{ lineNumber: 11, code: ' used[i] = false', indent: 2, type: 'action' },
161+
];
162+
```
163+
164+
### React Components Props
165+
166+
```typescript
167+
// Used 数组面板 Props
168+
interface UsedArrayPanelProps {
169+
state: UsedArrayState;
170+
}
171+
172+
// 递归栈面板 Props
173+
interface RecursionStackPanelProps {
174+
state: RecursionStackState;
175+
currentDepth: number;
176+
}
177+
178+
// 阶段指示器 Props
179+
interface PhaseIndicatorProps {
180+
state: PhaseIndicatorState;
181+
}
182+
183+
// 伪代码面板 Props
184+
interface PseudocodePanelProps {
185+
state: PseudocodeState;
186+
}
187+
```
188+
189+
## Data Models
190+
191+
### Extended Animation Step
192+
193+
```typescript
194+
// 扩展的动画步骤(包含算法解释信息)
195+
interface ExtendedAnimationStep extends AnimationStep {
196+
usedArray: boolean[];
197+
stackDepth: number;
198+
phase: BacktrackPhase;
199+
highlightedPseudocodeLine: number;
200+
}
201+
```
202+
203+
### Algorithm Explanation State
204+
205+
```typescript
206+
interface AlgorithmExplanationState {
207+
// Used 数组
208+
usedArrayState: UsedArrayState;
209+
210+
// 递归栈
211+
recursionStackState: RecursionStackState;
212+
213+
// 阶段指示
214+
phaseState: PhaseIndicatorState;
215+
216+
// 伪代码
217+
pseudocodeState: PseudocodeState;
218+
}
219+
```
220+
221+
## Correctness Properties
222+
223+
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
224+
225+
### Property 1: Used Array Consistency
226+
*For any* animation step with a current path, the used array SHALL have `true` for exactly those numbers that appear in the current path, and `false` for all other numbers.
227+
**Validates: Requirements 1.1, 1.2, 1.3**
228+
229+
### Property 2: Stack Depth Equals Path Length
230+
*For any* animation step, the recursion stack depth SHALL equal the length of the current path.
231+
**Validates: Requirements 2.1, 2.2, 2.3**
232+
233+
### Property 3: Stack Frame Path Consistency
234+
*For any* stack frame at depth d, the path stored in that frame SHALL be a prefix of length d of the current path.
235+
**Validates: Requirements 2.4**
236+
237+
### Property 4: Phase Indicator Correctness
238+
*For any* select step, the phase indicator SHALL show "choose" with the last number in the current path. *For any* backtrack step, the phase indicator SHALL show "unchoose" with the number that was removed.
239+
**Validates: Requirements 3.1, 3.3**
240+
241+
### Property 5: Pseudocode Line Mapping
242+
*For any* step type, the highlighted pseudocode line SHALL correspond to the correct action: select → line 7/8, backtrack → line 10/11, complete → line 3.
243+
**Validates: Requirements 4.2, 4.3, 4.4, 4.5**
244+
245+
## Error Handling
246+
247+
### State Inconsistency
248+
249+
| Error Condition | Handling |
250+
|----------------|----------|
251+
| Used array length mismatch | Reset to match input numbers length |
252+
| Stack depth exceeds input size | Cap at input size |
253+
| Invalid phase for step type | Default to 'idle' phase |
254+
| Pseudocode line out of range | Highlight no line |
255+
256+
### Edge Cases
257+
258+
- 空输入数组:显示空的 used 数组和栈
259+
- 单元素数组:栈深度最大为 1
260+
- 动画重置:清空所有状态到初始值
261+
262+
## Testing Strategy
263+
264+
### Unit Testing
265+
266+
使用 Vitest 进行单元测试:
267+
268+
- `UsedArrayTracker.getUsedArray` 的状态计算
269+
- `StackFrameBuilder.buildStack` 的栈构建
270+
- `PseudocodeMapper.getHighlightedLine` 的行映射
271+
- React 组件的渲染和状态显示
272+
273+
### Property-Based Testing
274+
275+
使用 fast-check 进行属性测试:
276+
277+
- 配置每个属性测试运行至少 100 次迭代
278+
- 每个属性测试必须标注对应的正确性属性
279+
- 格式:`**Feature: algorithm-explanation-enhancement, Property {number}: {property_text}**`
280+
281+
测试重点:
282+
1. Used 数组与当前路径的一致性
283+
2. 递归栈深度与路径长度的对应关系
284+
3. 阶段指示器与步骤类型的匹配
285+
4. 伪代码高亮行与步骤类型的映射
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Implementation Plan
2+
3+
- [ ] 1. Implement Used Array tracking and visualization
4+
- [ ] 1.1 Create UsedArrayTracker utility
5+
- Create `src/engine/usedArrayTracker.ts`
6+
- Implement `getUsedArray(inputNumbers, currentPath)` function
7+
- Implement `getChangedIndex(prevPath, currentPath, inputNumbers)` function
8+
- _Requirements: 1.1, 1.2, 1.3_
9+
- [ ] 1.2 Write property test for Used Array consistency
10+
- **Property 1: Used Array Consistency**
11+
- **Validates: Requirements 1.1, 1.2, 1.3**
12+
- [ ] 1.3 Create UsedArrayPanel component
13+
- Create `src/components/UsedArrayPanel.tsx` and CSS
14+
- Display each number with its used status (true/false)
15+
- Add animation for status changes
16+
- Use green for used (true), gray for unused (false)
17+
- _Requirements: 1.1, 1.4_
18+
19+
- [ ] 2. Implement Recursion Stack visualization
20+
- [ ] 2.1 Create StackFrameBuilder utility
21+
- Create `src/engine/stackFrameBuilder.ts`
22+
- Implement `buildStack(currentPath, available, inputNumbers)` function
23+
- Return array of StackFrame objects with depth, path, available, currentChoice
24+
- _Requirements: 2.1, 2.4_
25+
- [ ] 2.2 Write property tests for Recursion Stack
26+
- **Property 2: Stack Depth Equals Path Length**
27+
- **Property 3: Stack Frame Path Consistency**
28+
- **Validates: Requirements 2.1, 2.2, 2.3, 2.4**
29+
- [ ] 2.3 Create RecursionStackPanel component
30+
- Create `src/components/RecursionStackPanel.tsx` and CSS
31+
- Display stack frames as vertical list (bottom = depth 0)
32+
- Show depth level, path state, and current choice for each frame
33+
- Animate push/pop operations
34+
- _Requirements: 2.1, 2.2, 2.3, 2.4_
35+
36+
- [ ] 3. Implement Phase Indicator
37+
- [ ] 3.1 Create phase determination utility
38+
- Create `src/engine/phaseTracker.ts`
39+
- Implement `getPhase(stepType, currentPath, prevPath)` function
40+
- Return phase type and target number
41+
- _Requirements: 3.1, 3.3_
42+
- [ ] 3.2 Write property test for Phase Indicator
43+
- **Property 4: Phase Indicator Correctness**
44+
- **Validates: Requirements 3.1, 3.3**
45+
- [ ] 3.3 Create PhaseIndicator component
46+
- Create `src/components/PhaseIndicator.tsx` and CSS
47+
- Display current phase with icon and description
48+
- Use distinct colors: green (选择), blue (探索), orange (撤销), purple (完成)
49+
- _Requirements: 3.1, 3.2, 3.3, 3.4_
50+
51+
- [ ] 4. Implement Pseudocode Panel with sync highlighting
52+
- [ ] 4.1 Create PseudocodeMapper utility
53+
- Create `src/engine/pseudocodeMapper.ts`
54+
- Define BACKTRACK_PSEUDOCODE constant with line definitions
55+
- Implement `getHighlightedLine(stepType)` function
56+
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5_
57+
- [ ] 4.2 Write property test for Pseudocode mapping
58+
- **Property 5: Pseudocode Line Mapping**
59+
- **Validates: Requirements 4.2, 4.3, 4.4, 4.5**
60+
- [ ] 4.3 Create PseudocodePanel component
61+
- Create `src/components/PseudocodePanel.tsx` and CSS
62+
- Display pseudocode with syntax highlighting
63+
- Highlight current execution line based on step type
64+
- Add smooth transition for line highlight changes
65+
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5_
66+
67+
- [ ] 5. Checkpoint - Ensure all tests pass
68+
- Ensure all tests pass, ask the user if questions arise.
69+
70+
- [ ] 6. Integrate new components into App
71+
- [ ] 6.1 Update App state management
72+
- Add usedArrayState, recursionStackState, phaseState, pseudocodeState to App
73+
- Update handleStepChange to compute new states
74+
- _Requirements: 1.1, 2.1, 3.1, 4.1_
75+
- [ ] 6.2 Add new panels to layout
76+
- Integrate UsedArrayPanel into left panel or state bar
77+
- Integrate RecursionStackPanel into right panel
78+
- Integrate PhaseIndicator into step explanation area
79+
- Replace or enhance JavaDebuggerPanel with PseudocodePanel
80+
- _Requirements: 1.1, 2.1, 3.1, 4.1_
81+
- [ ] 6.3 Add responsive styling
82+
- Ensure new panels work on 768px - 1920px screens
83+
- Add smooth transitions for state changes
84+
- _Requirements: 1.4, 3.4_
85+
86+
- [ ] 7. Implement pruning indicators (optional enhancement)
87+
- [ ] 7.1 Add pruning tooltip to tree nodes
88+
- Enhance TreeVisualization to show tooltip on hover for unexplored nodes
89+
- Explain why branch was pruned (number already used)
90+
- _Requirements: 5.2, 5.3_
91+
92+
- [ ] 8. Final Checkpoint - Ensure all tests pass
93+
- Ensure all tests pass, ask the user if questions arise.

0 commit comments

Comments
 (0)