【问题标题】:CS50 Runoff - why does the 'strcmp() function' in my code actually work?CS50 径流 - 为什么我的代码中的“strcmp() 函数”实际上有效?
【发布时间】:2020-09-11 08:23:15
【问题描述】:

虽然我已经成功完成了练习bool vote(int voter, int rank, string name) 的投票功能部分,但我并没有真正看到计算机如何通过代码行:if (strcmp(candidates[i].name, name) == 0) 在下面的投票功能中是正确的。

例如,假设您输入 3 个候选人作为 argv's。 "dim", "oli" & "mat" 按此顺序。选民 0 在int main// Keep querying for votes 部分选择'mat dim oli' 作为他的偏好。

那么if (strcmp(candidates[i].name, name) == 0) 怎么可能是正确的?

因为在第一个循环中,i = 0candidates[i].name 等于 "dim" (argv [0 + 1]) 但第一个投票者选择 "mat" 作为他的首选(排名 0)实际上是 (argv [2 + 1] ) 与"dim" (argv [0 + 1]) 不匹配,不是吗?

也许在这种情况下逐步解释循环如何工作会有所帮助。

// preferences[i][j] is jth preference for voter i
int preferences[MAX_VOTERS][MAX_CANDIDATES];

// Candidates have name, vote count, eliminated status
typedef struct
{
    string name;
    int votes;
    bool eliminated;
}
candidate;

// Array of candidates
candidate candidates[MAX_CANDIDATES];

// Numbers of voters and candidates
int voter_count;
int candidate_count;

// Function prototypes
bool vote(int voter, int rank, string name);


int main(int argc, string argv[])
{
 
    // Populate array of candidates
    candidate_count = argc - 1;
    
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i].name = argv[i + 1];
        candidates[i].votes = 0;
        candidates[i].eliminated = false;
    }

    voter_count = get_int("Number of voters: ");
    
    // Keep querying for votes
    for (int i = 0; i < voter_count; i++)
    {
        // Query for each rank
        for (int j = 0; j < candidate_count; j++)
        {
            string name = get_string("Rank %i: ", j + 1);

            // Record vote, unless it's invalid
            if (!vote(i, j, name))
            {
                printf("Invalid vote.\n");
                return 4;
            }
        }
        printf("\n");
    }

// Record preference if vote is valid
bool vote(int voter, int rank, string name)
{
    // TODO
    for (int i = 0; i < candidate_count; i++)
    {
        **if (strcmp(candidates[i].name, name) == 0)**
        {
        preferences[voter][rank] = i;
        return true;
        }
    }
    return false;
}

【问题讨论】:

  • 这只是在候选数组中查找具有匹配名称的候选数组。如果找到匹配项,它会记录投票并停止迭代。你的解释中所有+1 的东西是怎么回事? C 数组是零索引的。
  • 请不要忘记minimal reproducible exampleminimal 部分。很难找到您要询问的单一陈述。
  • 使用调试器并逐步执行您的代码。或者至少在代码中的关键点放置一些 printfs,这样你就可以看到发生了什么。
  • @Someprogrammerdude - 我只删减了与我的问题相关的代码。现在清楚了吗?仍在学习与 SF 合作。感谢您的评论。
  • @tadman 现在说得通了,谢谢。 +1 我只是指候选人[i].name = argv[i + 1];当输入 i = 0, i = 1,... 就像我的例子一样。

标签: c cs50


【解决方案1】:

strcmp 的返回值视为“差异”,其中0 表示“没有差异”,换句话说,匹配。如果您遇到困难,您的第一站应该是the documentation,因为这就是我们所有人了解事情应该如何运作的方式。

换句话说,strcmp("dim","dim") 将是 0

【讨论】:

  • 这就是为什么我经常喜欢做#define streq !strcmp,消除了很多困惑
  • @joH1 请不要。只需使用strcmp,不要发明自己的C 方言,没人能听懂。一开始可能会有点混乱,但你很快就会习惯的。
  • @joH1 ...并将其替换为您的个人秘密宏语言,一点也不混乱。
  • @joH1:您的宏定义的唯一问题是它不符合语法,因此在某些情况下替换它可能会产生意想不到的结果。如果您改为将其定义为#define streq(a, b) (!strcmp((a), (b)),则它是一个类似函数的宏。忽略关于发明自己的方言/语言的抱怨。人们一直在编写子例程,并且以这种方式定义宏非常适合该范例。
  • @tadman 您在我的问题下的第一条评论实际上是我正在寻找的答案。至于你的回答,重新 strcmp 也很有用,谢谢。如果您想在答案部分添加您的第一条评论,请随意。无论哪种方式,我都接受答案。谢谢,感激不尽。
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 2014-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多