力扣 多数元素-169
多数元素-169
class Solution {
public:
int majorityElement(vector<int>& nums) {
//定义一个哈希数组,用来计nums数组中元素的个数
//因为普通数组索引不可以是负数,而题中数组中的元素可能有负数,所以选择用哈希数组
map<int,int> m;
//循环遍历数组nums
for(int i=0;i<nums.size();i++)
{
//每循环一个元素,就将nums的元素作为索引,索引的元素进行++操作,用来计数
m[nums[i]]++;
/*因为题目已经给出:可以假设数组是非空的,并且给定的数组总是存在多数元素。
所以直接对用来计数的哈希数组进行判断是否满足题意,满足直接返回多数元素*/
if(m[nums[i]]>nums.size()/2)
{
return nums[i];
}
}
return 0;
}
};
每日问题
什么是 C++ 内联函数?它的作用是什么?
1.内联函数的定义
在C++中,内联函数是一种特殊的函数,通过在函数定义前添加inine关键字来声明。例如
inline int add(int a, int b){
return a + b;
}
编译器在处理内联函数时,会尝试将函数调用出直接替换为函数体的代码,而不是像普通的函数那样进行函数调用的开销(如保存当前函数的执行上下文、跳转到被调用函数的入口地址、执行完后再返回等操作)。
2.内联函数的作用
提高程序性能(减少函数调用开销)
对于一些简单的、频繁调用的函数,函数调用的开销(包括保存寄存器状态、建立栈帧等操作)可能会在一定程度上影响程序的性能。内联函数可以避免这些开销。例如,一个简单的数学计算函数,如上面的add函数,如果在一个循环中被频繁调用:
for (int i = 0; i < 1000; ++i) {
int result = add(i, i + 1);
}
当add时内联函数时,编译器可能会将函数体 return a + b;直接插入到add(i, i+1)的调用位置,这样就避免了每次调用函数时的额外开销,从而可能提高程序的执行效率。
保持代码的结构化和可读性(类似宏的便利性)
内联函数和宏(#define)在某些方面有相似的功能,都可以在一定程度上减少函数调用的开销。但是宏存在一些潜在的问题,比如宏替换是简单的文本替换,没有类型检查,可能会导致意外的错误。而内联函数是真正的函数,具有函数的特性,如参数类型检查、返回值类型明确等。例如定义一个宏来实现加法:
#define ADD(a, b) a + b
当使用ADD(3 * 2, 4)时,可能会得到意想不到的结果(实际替换后是3 * 2 + 4,而不是先计算加法)。而内联函数inline int add(int a, int b){ return a + b ;}就不会出现这种问题,它在保证代码可读性(像普通函数一样有明确的参数和返回值)的同时,又能像宏一样在适当的情况下减少函数调用开销。
内联函数与普通函数有什么区别?如何定义和使用内联函数?
1.内联函数与普通函数的区别
调用方式和开销
普通函数:当调用普通函数时,程序需要执行一系列操作,如保存当前函数的执行上下文(包括寄存器的值、当前指令指针等),将参数压栈,跳转到被调用函数的入口地址,执行被调用函数的代码,最后在函数返回时恢复之前保存的执行上下文。这些操作会带来一定的时间和空间开销,特别是在函数频繁调用时,这种开销可能会比较明显。
内联函数:编译器会尝试将内联函数的代码直接嵌入到调用该函数的地方,而不是进行传统的函数调用操作。这样就避免了函数调用的额外开销。不过,这并不意味着内联函数完全没有开销,只是在适当的情况下可以减少函数调用相关的开销
代码空间占用
普通函数:普通函数的代码在内存中只有一份,无论它在程序中被调用多少次,都是通过函数调用指令跳转到同一个函数代码位置进行执行。因此,普通函数在代码空间占用上相对较为节省,不会因为多次调用而导致代码量的显著增加。
内联函数:由于内联函数的代码可能会在每个调用点都被展开插入,所以可能会导致代码量的增加。如果内联函数本身的代码比较长,或者频繁调用,那么生成的可执行文件的大小可能会显著增加,占用更多的代码空间。
编译时的处理方式
普通函数:编译器会将普通函数作为一个独立的代码单元进行编译,生成独立的函数机器码,在链接阶段函数的调用和函数体进行关联。在运行时,根据函数调用指令来执行相应的函数。
内联函数:编译器在编译阶段会尝试将内联函数的代码嵌入到调用点,这个过程类似于文本替换。编译器会根据内联函数的定义和调用情况进行优化,例如,如果内联函数中有常量表达式,编译器可能会在编译时就计算出结果。
2.内联函数的定义和使用
定义内联函数
在C++中,定义内联函数有两种常见的方式。一种是在函数定义时在函数头部添加inline关键字。例如:
inline int add(int a, int b) {
return a + b;
}
另一种方式时将函数定义放在类的内部(对于成员函数),类内部定义的成员函数默认是内联函数。例如:
class Calculator {
public:
int subtract(int a, int b) {
return a - b;
}
};
这里的subtract函数是Calculator类的成员函数,由于它是在类内部定义的,所以它默认是内联函数。不过。这种默认内联的方式并不是绝对的,编译器可能会根据函数的复杂性等因素决定是否真正将其内联处理。
使用内联函数
使用内联函数于普通函数类似,通过函数名和参数列表来调用函数。例如:
int main() {
int result1 = add(3, 5); // 使用内联函数add
Calculator calculator;
int result2 = calculator.subtract(7, 2); // 使用类的成员内联函数subtract
return 0;
}
在调用内联函数时,编译器会根据函数是否适合内联(例如函数体简单、函数规模较小等因素)以及编译器的优化策略,来决定是否将函数体代码直接嵌入到调用点。
原文地址:https://blog.csdn.net/Sunyanhui1/article/details/143834507
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!