在插入排序的嵌套循环期间,通过引用传递的swift数组没有正确解包问题。
// - C ++ WORKS -
//在C ++中,此函数已经过测试并且可以正常工作:
struct moveRecord
{
int fromSquare;
int toSquare;
int capturedPiece;
int moveScore;
};
struct moveRecord m1 = {20, 28, 4, 0};
struct moveRecord m2 = {20, 29, 5, 0};
struct moveRecord m3 = {20, 30, 1, 0};
struct moveRecord m4 = {20, 31, 2, 0};
struct moveRecord m5 = {20, 32, 3, 0};
moves[0] = m1;
moves[1] = m2;
moves[2] = m3;
moves[3] = m4;
moves[4] = m5;
movesStr = moves2Str( moves, numMoves );
cout << "UNSORTED: " << movesStr << endl;
sortMoves( moves, numLegalMoves );
movesStr = moves2Str( moves, numMoves );
cout << "SORTED: " << movesStr << endl;
void sortMoves( moveRecord moves[], int numMoves )
{
int i, j;
struct moveRecord tempMove;
for (j=1; j<numMoves; j++) {
cout << "j=" << j << " of " << numMoves << endl;
tempMove = moves[j];
for (i=j-1; i>-1; i--) {
cout << " i=" << i << endl;
// need to compare abs() values, or else black & white get sorted differently
if ( abs(moves[i].capturedPiece) >= abs(tempMove.capturedPiece) ) {cout << "break" << endl; break;}
moves[i+1] = moves[i];
}
cout << "we are out of iLoop" << endl;
moves[i+1] = tempMove;
}
return;
}
在XCode日志中包含以下结果:
UNSORTED: e4.4 f4.5 g4.1 h4.2 a5.3
j=1 of 5
i=0
we are out of iLoop
j=2 of 5
i=1
break
we are out of iLoop
j=3 of 5
i=2
i=1
break
we are out of iLoop
j=4 of 5
i=3
i=2
i=1
break
we are out of iLoop
SORTED: f4.5 e4.4 a5.3 h4.2 g4.1
数组元素排序为:.4 .5 .1 .2 .3
到正确的顺序:.5 .4 .3 .2 .1
大! C ++正在做正确的事情。
// - SWIFT结果差异 -
func sortMoves( theMoves: inout [moveRecord])
{
var i : Int = 0
var j : Int = 0
var tempMove : moveRecord
let numMoves : Int = theMoves.count
for j in 1..<numMoves {
print("j=\(j) of \(numMoves)")
tempMove = theMoves[j]
for i in stride(from:j-1, through:0, by:-1) {
print(" i=\(i)")
// need to compare abs() values or black/white sort differently
if ( abs(theMoves[i].capturedPiece!) >= abs(tempMove.capturedPiece!) ) {print("break"); break}
theMoves[i+1] = theMoves[i]
}
print("we are out of iLoop")
theMoves[i+1] = tempMove
}
return
}
在XCode日志中包含以下结果:
Unsorted Moves: f4.4 g4.5 h4.1 a5.2 b5.3
j=1 of 5
i=0
we are out of iLoop
j=2 of 5
i=1
break
we are out of iLoop
j=3 of 5
i=2
i=1
i=0
break
we are out of iLoop
j=4 of 5
i=3
i=2
i=1
i=0
break
we are out of iLoop
Sorted Moves: f4.4 b5.3 a5.2 h4.1 h4.1
所以数组元素排序为:.4 .5 .1 .2 .3 错误序列:.4 .3 .2 .1 .1
代码在语义上与工作C ++代码相同, 然而 - 第一个条目没有排序,最后一个条目重复, 并且高位移动很少。 : - (
了解我们如何得到C ++日志:J = 3,i = 1&gt;破
并且在swift log中它变为:J = 3,i = 1 .. i = 0&gt;破
让我认为问题在于,当在IF条件下进行比较时,swift是如何展开通过引用传递的数组值。
一小时的研究表明:| By default, array parameters are immutable
| within the called function. To modify the copy
| of the array that is passed to insertionSort, add
| var before toSort in the function header (Swift 1.2)
这种变化是Swift 3:
|在Swift 3中,返回类型为inout [DONE]
所以我的问题是swift展开中的错误:move [i] .capturedPiece! 在做的时候:IF(移动![i]&gt; = tempMove){break} ??
我无法看到通过swift获得相同功能的方法,可以在C ++中实现
任何人都有任何关于在SWIFT 3中通过引用传递的数组进行插入排序的建议!?!?
约翰·彭纳(多伦多岛)答案 0 :(得分:1)
该问题与通过引用,值类型传递数组无关 或解开。真正的问题是在Swift中,
for i in stride(from:j-1, through:0, by:-1) { ... }
语句定义了一个仅在循环范围内有效的变量,可能隐藏了外部作用域中具有相同名称的变量。 你不能参考&#34;最后一个值&#34;之后的变量 循环语句(你可以在C中)。
在你的情况下,
i
为循环体的范围定义变量i
,隐藏在函数顶部定义的外部变量theMoves[i+1] = tempMove
。因此在
i
var i : Int = 0
// variable 'i' was never mutated; consider changing to 'let' constant
var j : Int = 0
// warning: initialization of variable 'j' was never used; consider replacing with assignment to '_' or removing it
始终为零,因为该变量从未更改过。
实际上,编译器会警告您这个问题:
func sortMoves( theMoves: inout [moveRecord])
{
for j in 1..<theMoves.count {
let tempMove = theMoves[j]
var i = j-1
while i >= 0 && abs(theMoves[i].capturedPiece!) < abs(tempMove.capturedPiece!) {
theMoves[i+1] = theMoves[i]
i -= 1
}
theMoves[i+1] = tempMove
}
}
稍微简化的代码的正确版本将是
enumerate()