查找int数组中的第一个匹配项

时间:2018-09-08 10:42:16

标签: c

我正在尝试编写一个函数gtk_init(&argc, &argv),以便在int数组数据中搜索等于first的元素,然后立即搜索第二个元素。如果发生这种情况,该函数将首先返回指向该元素的指针。如果该情况在数组中发生多次,则指针应指向第一个情况。 我的代码是这样的:

int* findPair(int* data, int numEls, int first, int second)

当我输入两个#include <stdio.h> int* findPair(int* data, int numEls, int first, int second) { int i = 0; int *n = NULL; for (i = 0; i < numEls; i++) { if(data[i] == first && data[i + 1] == second) { n = &data[i]; } } return n; } int main() { int data[] = {1, 10, 2, 1, 2, 1, 2}; int* p = findPair(data, 7, 1, 2); if (p != NULL) { printf("Found at position %zd\n", p - data); } else { puts("Not found"); } } 进行测试时,它指向第二次出现(位置5而不是位置3)。是否有提示我做错了?

2 个答案:

答案 0 :(得分:2)

for函数中的findPair循环不会在第一次出现一对时停止。相反,它会继续前进,寻找更多的货币对,并且每遇到一对货币对,它就会覆盖n。因此n将始终指向最后一次出现(好,指向最后一次出现的第一个元素)。

找到第一个匹配项后,您需要立即停止for循环。

使用break语句从循环中过早退出:

for (i = 0; i < numEls; i++) {
    if(data[i] == first && data[i + 1] == second) {
        n = &data[i];
        break;
    }
}

找到第一对后,n将被设置为指向该对的第一个元素,并且循环将立即退出,跳转到函数的return语句。

答案 1 :(得分:2)

是的,您的循环总是在数组中找到最右边的一对。看,如果找到匹配项,循环仍然继续,以后再重新分配n指向其他元素。

此外,如果您在数组中再添加一个元素:

int data[] = {1, 10, 2, 1, 2, 1, 2, 1};
int* p = findPair(data, 8, 1, 2);

行为将变得不确定(您的程序可能会出现段错误)

因此,传递数组的长度减去1即可起作用,或者更好的方法是,正确终止循环:

for (i = 0; i < numEls - 1; i++) {
    if(data[i] == first && data[i + 1] == second) {
        n = &data[i];
        break;
    }
}

作为额外的小优化,您可以在某些情况下避免进行额外的比较:

if(first != second) {
    for (i = 0; i < numEls - 1; ++i) {
        if(data[i + 1] == second) {
            if(data[i] == first) {
                n = &data[i];
                break;
            }
            else ++i;
        }
    }
    return n;
}

for (i = 0; i < numEls - 1; ++i) {
    if(data[i + 1] == first) {
        if(data[i] == first) {
            n = &data[i];
            break;
        }
    }
    else ++i;
}
return n;