子表格列左移后新索引计算问题及C#代码错误排查
问题分析与修正方案
你的代码存在的问题
- 列计算逻辑完全错误:你用
(maxColumnIndex - minColumnIndex + 1) % shiftCellToTheLeft(列数对移位位数取模),搞反了模运算的对象——应该是用移位位数对列数取模,得到实际需要移动的有效位数(因为移动整列数的位数等于回到原位)。同时直接用绝对索引相减,未处理子表格的起始偏移,导致结果超出预期范围。 - 行计算逻辑完全错误:
(maxColumnIndex - maxColumnIndex + 1) % shiftCellToTheLeft计算结果恒为1,完全未关联行的移位逻辑。行的变化应由移位位数跨越的完整列数决定,而非无意义的列索引差值。
正确公式的推导步骤
要解决子表格内的循环移位问题,核心是先将绝对索引转换为子表格内的相对索引(从0开始),计算移位后的相对索引,再转换回绝对索引:
计算子表格的行列总数:
- 列总数:
colCount = maxColumnIndex - minColumnIndex + 1 - 行总数:
rowCount = maxRowIndex - minRowIndex + 1
- 列总数:
计算有效移位位数:
移位整列数的倍数相当于回到原位,因此有效移位为:effectiveShift = shiftCellToTheLeft % colCount
若effectiveShift为0,说明刚好移了整数圈,等效于移动colCount位。计算目标列索引:
- 将原列转换为相对索引:
relativeCol = cellAColumnIndex - minColumnIndex - 左移后的相对列索引(加
colCount避免负数):newRelativeCol = (relativeCol - effectiveShift + colCount) % colCount - 转换回绝对索引:
cellBColumnIndex = minColumnIndex + newRelativeCol
- 将原列转换为相对索引:
计算目标行索引:
- 计算移位跨越的完整行数(整数除法):
rowShift = shiftCellToTheLeft / colCount - 将原行转换为相对索引:
relativeRow = cellARowIndex - minRowIndex - 移位后的相对行索引(加
rowCount避免负数):newRelativeRow = (relativeRow - rowShift + rowCount) % rowCount - 转换回绝对索引:
cellBRowIndex = minRowIndex + newRelativeRow
- 计算移位跨越的完整行数(整数除法):
修正后的C#代码
public static void Main() { int minColumnIndex = 4; int maxColumnIndex = 8; int minRowIndex = 2; int maxRowIndex = 5; int cellARowIndex = 4; int cellAColumnIndex = 7; int shiftCellToTheLeft = 11; // 计算子表格行列总数 int colCount = maxColumnIndex - minColumnIndex + 1; int rowCount = maxRowIndex - minRowIndex + 1; // 计算有效移位位数 int effectiveShift = shiftCellToTheLeft % colCount; if (effectiveShift == 0) effectiveShift = colCount; // 计算目标列索引 int relativeCol = cellAColumnIndex - minColumnIndex; int newRelativeCol = (relativeCol - effectiveShift + colCount) % colCount; int cellBColumnIndex = minColumnIndex + newRelativeCol; // 计算目标行索引 int rowShift = shiftCellToTheLeft / colCount; int relativeRow = cellARowIndex - minRowIndex; int newRelativeRow = (relativeRow - rowShift + rowCount) % rowCount; int cellBRowIndex = minRowIndex + newRelativeRow; Console.WriteLine("cellBColumnIndex: " + cellBColumnIndex); Console.WriteLine("cellBRowIndex: " + cellBRowIndex); // 输出结果: // cellBColumnIndex: 6 // cellBRowIndex: 2 }
内容的提问来源于stack exchange,提问作者CrazyEight
相关产品推荐
相关产品推荐

