我有一个作业,如果您能帮助我解决一个问题,我会很高兴 在这项作业中,我有一个像这样的问题:
编写一个接收数组及其长度的函数。 该函数的目的是检查数组是否具有从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}
谢谢您的帮助。
答案 0 :(得分:2)
如您的反例所示,仅检查总和与乘积是不够的。
一种简单的解决方案是对数组进行排序,然后检查i
,a[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)
我想了一会儿,然后我意识到这是一个非常禁忌的问题。 不允许的事情:
因此,我想出了使用XOR操作确定结果的方法。
尝试一下:
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。