[英]Problem with Objective-C for loop
我有兩個方法,在testMethod中調用generateRandomCard方法,其中有一個運行100次的for循環。 這樣它的工作完美,但是如果我將for循環限制設置為1000或任何其他大於100的數字,它就會崩潰。 你能看出什么問題嗎?
- (void)testMethod {
Globals *myGlobals = [Globals sharedInstance];
int rankOfFirst = 0;
int rankOfSecond = 0;
int playerOneWin = 0;
int playerTwoWin = 0;
int ties = 0;
float firstPercent = 0;
float secondPercent = 0;
float tiePercent = 0;
FiveEval *evaluator = [FiveEval theEvaluator];
for (int i = 0; i < 100; i++) {
short fPF = [self generateRandomCard];
short fPS = [self generateRandomCard];
short sPF = [self generateRandomCard];
short sPS = [self generateRandomCard];
short fFlop = [self generateRandomCard];
short sFlop = [self generateRandomCard];
short tFlop = [self generateRandomCard];
short tur = [self generateRandomCard];
short riv = [self generateRandomCard];
rankOfFirst = [evaluator getRankOfSeven:fFlop
:sFlop
:tFlop
:tur
:riv
:fPF
:fPS];
rankOfSecond = [evaluator getRankOfSeven:fFlop
:sFlop
:tFlop
:tur
:riv
:sPF
:sPS];
if (rankOfFirst > rankOfSecond) {
playerOneWin++;
} else if (rankOfSecond > rankOfFirst) {
playerTwoWin++;
} else {
ties++;
}
[myGlobals.alreadyPickedCards removeAllObjects];
}
firstPercent = ((float)playerOneWin/(float)10000)*100;
secondPercent = ((float)playerTwoWin/(float)10000)*100;
tiePercent = ((float)ties/(float)10000)*100;
NSLog(@"First Player Equity: %f", firstPercent);
NSLog(@"Second Player Equity: %f", secondPercent);
NSLog(@"Tie Equity: %f", tiePercent);
}
- (short)generateRandomCard {
Globals *myGlobals = [Globals sharedInstance];
short i = arc4random()%51;
for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
[self generateRandomCard];
}
}
[myGlobals.alreadyPickedCards addObject:[NSNumber numberWithShort:i]];
return i;
}
您可能在遞歸調用-generateRandomCard
溢出堆棧 。 如果你生成一張已經被挑選過的卡片,你會遞歸地調用自己(並忽略結果,這是一個不同的錯誤)。 所以,如果你的隨機數流給你一個不幸的序列,讓你已經選擇了你已經選擇的牌,那么你將無限地遞歸,直到堆棧溢出。
更改您的卡片選擇算法,以便不使用具有無限循環/遞歸潛力的拒絕采樣 ,而是使用具有有界運行時間的算法,例如Fisher-Yates shuffle 。
不確定這是否會以任何方式導致崩潰 - 它可能是無關的。 但是,當在alreadyPickedCards數組中找到卡時,看起來你在遞歸調用generateRandomCard的方式上有一個錯誤。 代替
[self generateRandomCard];
我想你應該有
return [self generateRandomCard];
你有-testMethod: [myGlobals.alreadyPickedCards removeAllObjects];
和ingenerateRandomCard你有:
for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
[self generateRandomCard];
}
}
我不能肯定地下注,但這看起來像是在一個循環中刪除AllObjects並在另一個循環中訪問一個out of bound索引的情況。
如果你想用數組這樣玩,我建議你制作數組的副本並從那些復制的數組中刪除項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.