c++实现找单独的数

144 阅读5分钟

题目连接:找单独的数

万能头文件:\

#include <bits/stdc++.h>
using namespace std;

using namespace std:

解释

  • namespace:命名空间是C++中用来组织代码的一种方式,它可以帮助避免不同库或模块之间的名称冲突。
  • std:这是C++标准库的命名空间,包含了C++标准库中定义的所有类、函数、对象等。

使用场景

当你在编写C++程序并使用标准库中的元素(如vector, string, cout等)时,你可以选择以下两种方式之一:

  1. 不使用using namespace std;

    cpp
    #include <iostream>
    #include <vector>
    
    int main() {
        std::vector<int> vec;
        vec.push_back(1);
        std::cout << "Hello, World!" << std::endl;
        return 0;
    }
    

    这种方式明确指出了每个标准库元素所属的命名空间,有助于避免命名冲突,但代码会显得冗长。

  2. 使用using namespace std;

    cpp
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main() {
        vector<int> vec;
        vec.push_back(1);
        cout << "Hello, World!" << endl;
        return 0;
    }
    

    这种方式使得代码更加简洁,但如果项目中使用了多个库,可能会导致命名冲突。

注意事项

  • 命名冲突:如果项目中使用了多个命名空间,且这些命名空间中有同名的元素,使用using namespace可能会导致冲突。
  • 代码可读性:在大型项目或团队协作中,明确使用std::前缀可以提高代码的可读性和维护性。
  • 局部使用:可以在函数或代码块中局部使用using namespace std;,以减少全局影响。

总之,using namespace std;是一个方便的工具,但在使用时应考虑到可能的命名冲突和代码的可维护性。在小型项目或示例代码中使用它通常是安全的,但在大型项目中应谨慎使用。

方法体代码:

int solution(std::vector<int> cards) {
    // Edit your code here
    int a[1100];
    memset(a, 0, sizeof(a));
    for(int i=0;i<cards.size();i++){
        a[cards[i]]++;
    }
    for(int i=0;i<=1000;i++){
        if(a[i]==1){
            return i;
            break;
        }
    }
    return 0;
}

代码思想:

  1. 数组大小和memset的使用

    • 您定义的数组a[1100]是为了存储0到1000的整数出现的次数。这是合理的,因为题目可能假设cards中的数字范围在0到1000之间。
    • 使用memset(a, 0, 110);是不正确的,因为memset的第三个参数是字节,而不是数组元素。这里应该使用memset(a, 0, sizeof(a));来确保整个数组被初始化为0。
    • memset 是 C 和 C++ 编程语言中的一个标准库函数,用于将一块内存中的所有字节设置为特定的值。这个函数在处理数组初始化或者内存区域填充时非常有用,尤其是在需要将内存设置为0或-1(0xFF)时。

函数原型

在 C++ 中,memset 函数的原型定义在 <cstring><string.h> 头文件中:

void* memset(void* ptr, int value, size_t num);

参数

  • ptr:指向需要设置值的内存区域的指针。
  • value:要设置的值。这个值会被转换为unsigned char,并且会被写入到内存区域的每一个字节中。
  • num:要设置的字节数。

返回值

函数返回指向ptr的指针,即被设置的内存区域的指针。

使用示例

以下是一些使用 memset 的示例:

初始化数组为0

#include <iostream>
#include <cstring>

int main() {
    int arr[10];
    memset(arr, 0, sizeof(arr)); // 将整个数组初始化为0

    for (int i = 0; i < 10; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

初始化数组为-1

#include <iostream>
#include <cstring>

int main() {
    int arr[10];
    memset(arr, -1, sizeof(arr)); // 将整个数组初始化为-1

    for (int i = 0; i < 10; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

注意事项

  • 数据类型memset 操作是以字节为单位的,因此当用于非字符类型的数组时(如int, float等),可能会得到意想不到的结果。例如,使用 memsetint 数组设置为 -1 时,每个字节都被设置为 0xFF,这在32位系统上会导致每个整数变成 0xFFFFFFFF(即 -1 的二进制表示)。
  • 对齐问题:由于 memset 是按字节操作的,它不考虑数据类型的对齐要求。这通常不是问题,但在特定情况下可能需要注意。

总之,memset 是一个非常有用的函数,特别是在需要快速初始化大型内存区域时。然而,使用时应确保理解其行为,特别是在处理非字符类型数据时。

  1. 逻辑正确性

    • 您的逻辑是正确的:遍历cards数组,统计每个数字出现的次数,然后再次遍历统计数组a,找出第一个出现次数为1的数字并返回。
  2. 代码优化

    • 您可以使用std::unordered_map来代替数组,这样可以处理更广泛的数字范围,并且代码更加通用。

下面是修改后的代码,包括使用memset的正确方式和一些小的改进:

cpp复制

int solution(std::vector<int> cards) {
    int a[1001]; // Assuming the range of numbers is from 0 to 1000
    memset(a, 0, sizeof(a)); // Correctly initialize the array to 0

    // Count the occurrences of each number
    for (int i = 0; i < cards.size(); i++) {
        if (cards[i] >= 0 && cards[i] <= 1000) { // Ensure the number is within the expected range
            a[cards[i]]++;
        }
    }

    // Find the first number that appears exactly once
    for (int i = 0; i <= 1000; i++) {
        if (a[i] == 1) {
            return i;
        }
    }

    return -1; // Return -1 if no unique number is found
}