如何检查数组中的所有值是否相同?

3
假设我有一个数组short int check[10] = {1,1,1,1,1,1,1,1,1};。 我想检查所有元素是否都相同。 我在stackoverflowgoogle上找不到答案,但我发现了这段C++代码。
bool aresame(int a[], int n)
{
    int i;
    unordered_map<int, int> m;

    for (i = 0; i < n; i++)
    {
        m[a[i]]++;
    }
    if (m.size() == 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

稍微调整一下,结果可能会产生巨大的误差。
我的尝试是使用if语句,但那很不专业。
还有其他方法吗?

2
为什么使用 if 是不专业的?遍历数组并将其与第一个条目进行比较。for (i=1; i<n; ++i) if (a[i] != a[0]) return false; return true; - Ashley Miller
3
你发现了C++代码,但是你需要用C语言解决方案?那么不要浪费时间去看那段代码。你尝试过一些简单直接的方法,比如“循环遍历每个索引,并检查该元素是否与第一个元素相同”吗?你自己的尝试出了什么问题? - Gerhardh
3
只有在使用不专业的方式时,才会使 “if” 不专业。如果使用得当,则“if”并没有错误。 - Gerhardh
2
在for循环中使用if比递增map元素更加“专业”。 - William Pursell
记住,如果你总是在 if 的一个分支中使用 return,那么其后的所有内容都会默认成为 else,因此你可以跳过那部分并将其压缩一下。 - tadman
5个回答

3
正如Gerhardh在评论中指出的那样,使用if并没有不专业。以下代码应该可以工作:
#include <stdbool.h>

bool are_same(int *arr, unsigned int len)
{
    for (int i = 1; i < len; ++i)
        if (arr[0] != arr[i])
            return false;
    return true;
}

您可以这样调用函数are_same:
int arr[] = {1, 1, 1, 1, 1};
unsigned int len = sizeof(arr) / sizeof(int);
printf("The elements in the array are %s.\n",
       are_same(arr, len) ? "all the same" : "not all the same");

3

if 是完全没问题的,它并不会显得不专业

需要说明的是,在 short int check[10] = {1,1,1,1,1,1,1,1,1}; 中只有9个元素是1,最后一个元素将被初始化为0,因此如果你省略数组大小,即例如 check[] = {1,1,1...,你就不会遇到这个问题,因为数组的大小会根据初始化器中元素的数量自动推断。

#include <stdio.h>
#include <stdbool.h>

bool aresame(short int a[], size_t n) // added value to check
{
    for (size_t i = 1; i < n; i++)
    {
        if(a[i] != a[0])
            return false; // if a different value is found return false
    }
    return true; // if it reaches this line, all the values are the same
}

int main()
{
    short int check[]={1,1,1,1,1,1,1,1,1};
    printf("%s", aresame(check, sizeof check / sizeof *check) ? "true" : "false");
}

演示实况


2

如果您不喜欢使用if语句,可以尝试以下方法:

bool aresame(int a[], int n) {
    int i = 0;
    while(i<n && a[i]==a[0]) 
        i++;
    return i == n;
}

不需要使用额外的本地存储,只需循环直到找到一个不同的元素。如果到达末尾,则一切正常。否则不行。
请参见此处:https://godbolt.org/z/8r6YK6W34

2

为了完整起见,这里提供一个递归版本(没有显式的if语句):

bool aresame(int a[],int n){
    return (n <= 1) || (a[0] == a[n-1] && aresame(a, n-1));
}

1

这是一个快速而简单的实现,假设使用二进制补码且没有填充位:

if
#include <stdbool.h>
#include <string.h>

bool are_same(const int *arr, size_t n) {
    return n == 0 || !memcmp(arr, arr + 1, (n - 1) * sizeof(*arr));
}

你可以将此方法推广到检查数组是否包含长度为r的重复序列:
#include <stdbool.h>
#include <string.h>

bool is_repeating(const int *arr, size_t n, size_t r) {
    return n <= r || !memcmp(arr, arr + r, (n - r) * sizeof(*arr));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接