DrRacket中Scheme矩阵setCell函数嵌套列表问题求助
setCell Function Hey, let's break down why your setCell function is creating those unwanted nested lists when modifying cells outside the first row and first column, and how to fix it.
What's Going Wrong
The core issue is in how your recursion mixes row-level and matrix-level operations. When you modify a cell that's not in the first row/column, your code treats the remaining part of a row as a tiny matrix (like ((3 5 7)) instead of just the flat list (3 5 7)). Then when you combine the first element of the row with the recursive result, you end up nesting the modified sublist inside another list.
Let's walk through your failed test case step by step:
- When you call
(setCell Matrix 2 2 9), the function first skips the first row and callssetCellon'((1 3 5 7) (2 9 0 1))with row 1, column 2. - Since column isn't 1, it takes the first element of the current row (
1) and tries to combine it withsetCellof'((3 5 7))(the rest of the row) at row 1, column 1. - That inner
setCellreturns'((9 5 7))—a full matrix with one row. So when you do(cons 1 '((9 5 7))), you get(1 (9 5 7))instead of the flat list you need.
How to Fix It
We need to split the problem into two focused helper functions: one to update a single row's element, and another to navigate the matrix and replace the target row. This separation keeps row-level and matrix-level logic clean.
Revised Code
(define Matrix '((2 4 6 8) (1 3 5 7) (2 9 0 1))) ; Helper: Updates a single row to set the nth column to the new item (define (update-row row column new-item) (if (= column 1) (cons new-item (cdr row)) (cons (car row) (update-row (cdr row) (- column 1) new-item)))) ; Main function: Finds the target row, updates it, and puts it back in the matrix (define (setCell Matrix Row Column Item) (if (= Row 1) (cons (update-row (car Matrix) Column Item) (cdr Matrix)) (cons (car Matrix) (setCell (cdr Matrix) (- Row 1) Column Item)))) ; Test cases to verify (setCell Matrix 2 2 9) ; Returns ((2 4 6 8) (1 9 5 7) (2 9 0 1)) ✔️ (setCell Matrix 1 1 9) ; Returns ((9 4 6 8) (1 3 5 7) (2 9 0 1)) ✔️ (setCell Matrix 3 4 0) ; Returns ((2 4 6 8) (1 3 5 7) (2 9 0 0)) ✔️
What Changed
update-rowfocuses solely on modifying single rows. It recursively walks through the row and replaces the target column, returning a flat modified row (not a matrix). For example,(update-row '(1 3 5 7) 2 9)directly gives(1 9 5 7).setCellnow only handles navigating to the correct row in the matrix. Once it finds the row to modify, it usesupdate-rowto fix that row, then puts it back into the matrix structure. No more nesting because we're always combining lists at the correct level.
This separation of concerns eliminates the nested list bug and makes the code easier to read and debug.
内容的提问来源于stack exchange,提问作者k778899

