在数组中查找匹配的连续整数

时间:2017-05-09 12:08:54

标签: c arrays

给定两个包含整数的数组,确定两个数组中是否存在三个连续的整数。 例如:A = [1,4,5,7,2]和B = [3,1,4,5,9]将导致" true" / 1因为[1,4,5]存在于两个数组中。

我的解决方案如下所示,但我觉得必须有一个比这更优化的解决方案。

int consecutiveInts(int *a, int sizeA, int *b, int sizeB){
    int i, j;

    // Iterate over every integer in array b for every integer in array a.
    for (i = 0 ; i < sizeA - 2 ; i++){
        for (j = 0 ; j < sizeB - 2 ; j++){
            if (a[i] == b[j] && a[i + 1] == b[j + 1] && a[i + 2] == b[j + 2])
                return 1;
        }
    }
    return 0;
}

5 个答案:

答案 0 :(得分:0)

我认为我不能错,因为声明循环之外的i和j是无用的而且没有优化。

类似的东西:

for (unsigned i = 0; i < sizeA - 2; i++) // i will only exist inside the loop

会好一点。 我使用无符号类型,因为这是我在使用迭代变量时所采取的习惯。我认为这是一个问题,如果您感兴趣并且尚未得到通知,您可以通过阅读this主题来学习。

答案 1 :(得分:0)

不确定它是否优化了运行速度,但我注意到如果有重复的数字,您不需要反复检查它们。

例如,第一个数组中的三个连续元素都是1。检查a[i]并查看不匹配后,您可以直接跳至a[i + 3],而无需比较a[i + 1]a[i + 2](它们也不匹配)。

这种情况的管理,特别是如果它是一个短的重复序列,可能不会改善运行时间。你必须衡量。

答案 2 :(得分:0)

如果代码更改不影响order of complexity,则任何候选者改进都需要分析(测量性能的测试)以进行验证。

以下仍然是O(n * m),但系数降低,因为如果b[]具有a[]中也存在的重复值,它可以更快地逐步b[]。这会加速消耗大部分时间的内部b[]循环。

查看不同值的a[]模式,以便j可以更快地推进。{ 例如:

#define x 0
bool Pattern3(const int *a, size_t size_a, const int *b, size_t size_b) {
  static const unsigned char deltas[2][2][2][2] = { //
      //                 What type of pattern is a[0], a[1], a[2]?
      { { { 1, 1 },   // X Y Z
      { 1, 1 } },     // X Y Y
      { { 1, 2 },     // X Y X
      { x, x } } },   // not possible
      { { { 2, 1 },   // X X Y
      { x, x } },     // not possible
      { { x, x },     // not possible
      { 2, 3 } } } }; // X X X
  for (unsigned i = 0; i + 2 < size_a; i++) {
    const unsigned char *delta23 = deltas[a[0] == a[1]][a[0] == a[2]][a[1] == a[2]];
    for (unsigned j = 0; j + 2 < size_b;) {
      if (a[0] != b[j]) {
        j++;
      } else if (a[0 + 1] != b[j + 1]) {
        j += delta23[0];
      } else if (a[0 + 2] != b[j + 2]) {
        j += delta23[1];
      } else {
        return true;
      }
    }
    a++;
  }
  return false;
}

其他可能有所帮助的微小变化。

在上文中,a,b时交换size_a > size_b

使用const,因为较小的编译器可以对此进行优化。

// int consecutiveInts(int *a, int sizeA, int *b, int sizeB){
int consecutiveInts(const int *a, int sizeA, const int *b, int sizeB){

迭代2.相应地调整索引。

for (i = 2 ; i < sizeA ; i++){
  ...

答案 3 :(得分:0)

对于小型阵列,OP方法可以。对于数组长度m,n,它的运行时间为O(m*n)

备用数据库生成2个值数组,对它们进行排序,然后查找公共元素。它有O(m*log2(m) + n*log2(n))运行时间。使用大型数组肯定比OP的代码更快。

typedef struct {
  int i[3];
} int3;

void Init3(int3 *i3, const int *i, size_t n) {
  while (n--) {
    i3[n].i[0] = i[n];
    i3[n].i[1] = i[n + 1];
    i3[n].i[2] = i[n + 2];
  }
}

int fcmp(const void *a, const void *b) {
  return memcmp(a, b, sizeof (int3));
}

bool Pattern3(const int *a, size_t size_a, const int *b, size_t size_b) {
  if (size_a < 3 || size_b < 3) return false;

  int3 a3[size_a - 2];
  Init3(a3, a, size_a - 2);
  qsort(a3, size_a - 2, sizeof *a3, fcmp);

  int3 b3[size_b - 2];
  Init3(b3, b, size_b - 2);
  qsort(b3, size_b - 2, sizeof *b3, fcmp);

  while (size_a && size_b) {
    int cmp = fcmp(&a[size_a - 1], &b[size_b - 1]);
    if (cmp == 0) return true;
    if (cmp > 0) size_a--;
    else size_b--;
  }
  return false;
}

int main() {
  int A[] = { 1, 4, 5, 7, 2 };
  int B[] = { 3, 1, 4, 5, 9 };
  printf("%d\n", Pattern3(A, sizeof A / sizeof *A, B, sizeof B / sizeof *B));
}

替代方案是使用bsearch()而不是形成第二个int3 b3[]/qsort()

答案 4 :(得分:-1)

尝试使用以下循环

messageTracker(index, message) {
  return message? message.id : undefined;
}