[英]CS50 - PSET 3 - Tideman - lock_pairs() works when I test it, but fails unit testing
[英]PSET 3 Tideman CS50 lock_pairs doesn't lock correctly
我是這個網站的新手,所以我可能無法正確提出我的問題,對此我很抱歉,但我已經在 PSET 3 Tideman 上苦苦掙扎了一段時間。 目前我在 lock_pairs 上,我不知道該怎么做。 感謝您的幫助:這些是我對 check50 的提示:
:) lock_pairs locks all pairs when no cycles
:( lock_pairs skips final pair if it creates cycle
lock_pairs did not correctly lock all non-cyclical pairs
:( lock_pairs skips middle pair if it creates a cycle
lock_pairs did not correctly lock all non-cyclical pairs
void lock_pairs(void)
{
int winner;
int win_count[MAX];
int temp_win = 0;
for (int i = 0; i < pair_count; i++)
{
locked[ pairs[i].winner ][ pairs[i].loser ] = true;
win_count[ pairs[i].winner ]++;
if (win_count [ pairs[i].winner ] > temp_win )
{
winner = pairs[i].winner;
}
}
for ( int p = 0; p < pair_count; p++)
{
if (win_count[ pairs[p].winner ] == win_count[winner] && pairs[p].winner != winner )
{
for (int i = pair_count - 1; i < -1 ; i--)
{
locked[ pairs[i].winner ][ pairs[i].loser ] = false;
win_count [ pairs[i].winner ]--;
if (pairs[i].winner == winner )
{
win_count[winner]--;
for (int j = 0; j < pair_count; j++)
{
if (win_count[ pairs[j].winner ] > win_count[winner])
{
winner = pairs[j].winner;
}
if (win_count[ pairs[j].winner] == win_count[winner] && pairs[j].winner != winner)
{
break;
}
}
}
else
{
locked[ pairs[i].winner ][ pairs[i].loser ] = true;
}
}
}
}
return;
}
您可能誤解了lock_pairs
背后所需的邏輯,因為您的 function 過於復雜。 這是你被要求做的——
Go 每對一一通過,必要時鎖定
如何知道,如果有必要? 很簡單,您確保鎖定它們不會構成一個圓圈
“構成一個圓”是什么意思? 課程本身很好地解釋了這一點。 更多信息就在那里
但基本上,
在上述投票的情況下,這將如何運作? 好吧,一對勝利的最大優勢是愛麗絲擊敗鮑勃,因為有 7 個選民更喜歡愛麗絲而不是鮑勃(沒有其他正面對決的獲勝者被超過 7 個選民喜歡)。 所以 Alice-Bob 箭頭首先被鎖定在圖中。 下一個最大的勝利是查理以 6-3 戰勝愛麗絲,因此箭被鎖定在下一個。
接下來是鮑勃以 5-4 戰勝查理。 但請注意:如果我們現在要添加一個從 Bob 到 Charlie 的箭頭,我們將創建一個循環,由於該圖不允許循環,我們應該跳過這條邊。 並且根本不將其添加到圖表中,如果要考慮更多箭頭,我們將查看下一個箭頭,但那是最后一個箭頭。 所以圖是完整的。
這個分步過程如下所示,最終圖表在右側。
現在真正的交易,你如何把它放在代碼中?
像這樣-
// Recursive function to check if entry makes a circle bool makes_circle(int cycle_start, int loser) { if (loser == cycle_start) { // If the current loser is the cycle start // The entry makes a circle return true; } for (int i = 0; i < candidate_count; i++) { if (locked[loser][i]) { if (makes_circle(cycle_start, i)) { // Forward progress through the circle return true; } } } return false; }
本質上,要檢查鎖定贏家->輸家是否形成了一個圓圈,您從失敗者開始退回您鎖定的條目,並走向該失敗者贏得的所有候選人。 如果您在途中的某個地方到達獲勝者,那是一個圓圈,如果我見過的話。
請注意circle_start
,以免混淆。 那只是為了記住最初的循環開始(這是lock_pairs
主循環中的winner
)。 這在整個遞歸過程中是恆定的。 再一次記住,我們的目標是遍歷所有loser
已經戰勝(並且也被鎖定)的候選人,並確保這些候選人都不是circle_start
(也就是我們即將鎖定的winner
)。
因此,function 就在那里完成了所有繁重的工作,您的lock_pairs
function 將非常簡單-
// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs()
{
for (int i = 0; i < pair_count; i++)
{
if (!makes_circle(pairs[i].winner, pairs[i].loser))
{
// Lock the pair unless it makes a circle
locked[pairs[i].winner][pairs[i].loser] = true;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.