检查数组中是否包含从0到C中的长度-1的数字

时间:2019-01-31 13:39:46

标签: c arrays

我有一个作业,如果您能帮助我解决一个问题,我会很高兴 在这项作业中,我有一个像这样的问题:

编写一个接收数组及其长度的函数。 该函数的目的是检查数组是否具有从0到length-1的所有数字,如果是,则该函数将返回1或0,否则该函数只能通过该数组。 您无法对数组进行排序或在函数中使用计数数组

我编写了一个函数,用于计算数组的值和索引的和以及乘积

int All_Num_Check(int *arr, int n)
{
 int i, index_sum = 0, arr_sum = 0, index_multi = 1, arr_multi = 1;

 for (i = 0; i < n; i++)
  {
    if (i != 0)
       index_multi *= i;
    if (arr[i] != 0)
       arr_multi *= arr[i];

    index_sum += i;
    arr_sum += arr[i];
  }

 if ((index_sum == arr_sum) && (index_multi == arr_multi))
    return 1;

 return 0;
}

即:length = 5,arr = {0,3,4,2,1}-这是一个适当的数组 length = 5,arr = {0,3,3,4,2}-这不是正确的数组

不幸的是,此功能在所有不同的数字变化情况下均无法正常工作。 即:length = 5,{1,2,2,2,3}

谢谢您的帮助。

2 个答案:

答案 0 :(得分:2)

如您的反例所示,仅检查总和与乘积是不够的。

一种简单的解决方案是对数组进行排序,然后检查ia[i] == i的每个位置。

编辑:原始问题已被编辑,因此也禁止排序。假设所有数字都是正数,下面的解决方案通过否定相应的索引在所需范围内“标记”数字。 如果任何数组单元格已经包含标记的数字,则表示我们有一个重复项。

int All_Num_Check(int *arr, int n) {
  int i, j;

  for (i = 0; i < n; i++) {
      j = abs(arr[i]);
      if ((j >= n) || (arr[j] < 0)) return 0;  
      arr[j] = -arr[j];
  }

  return 1;
}

答案 1 :(得分:-2)

我想了一会儿,然后我意识到这是一个非常禁忌的问题。 不允许的事情:

  1. 计数数组的使用。
  2. 使用排序。
  3. 对原始数组使用了多次传递。

因此,我想出了使用XOR操作确定结果的方法。

  1. a ^ a = 0
  2. a ^ b ^ c = a ^ c ^ b。

尝试一下:

int main(int argc, char const *argv[])
{
    int arr[5], i, n , temp = 0;
    for(i=0;i<n; i++){
        if( i == 0){
            temp = arr[i]^i;
        }
        else{
            temp = temp^(i^arr[i]);
        }
    }
    if(temp == 0){
        return 1;
    }
    else{
        return 0;
    }
}

要满足问题中提到的条件,每个数字都必须占用一次。
现在,由于数字在[0,.. n-1]范围内,因此循环变量也将具有相同的可能范围。
变量temp最初设置为0。
现在,如果所有数字都以这种方式出现,那么每个数字都会出现两次。
并且对相同数字进行两次异或运算将得出0。
因此,如果最后遍历整个数组并获得零,则意味着该数组完全包含一次所有的数字。
否则,将存在一个数字的多个副本,因此,该副本的值不会为0。