选择题
二维数组的初始化,不同的语言有些不同,有些遗忘
这一题涉及到函数栈帧、大小端问题,值得思考一下
题目所给是32位下小端机器,但是如果再64位机器下,结果却是: 1,2,3
这是为什么呢?这就要结合体系结构来说了
- 事实上,32位机器下和64位机器下的传参是不同的,32位机器的寄存器的32位的,long long为8字节,所以每一个变量需要传递两次才可以,因此 abc相当于传递了6次参数,打印的时候也需要CPU中的寄存器去参与,并且由于栈的后进先出,所以最终取出的是最后三次传递的数据
- 而64位机器下,寄存器也是64位的,所以每一次传参都可完整的传过去,所以只需要传递三次。当然取出来的时候,自然就把整个取出来了!
你可能想说,%d不是打印int类型吗?难道64位下%d是打印8个字节吗? 其实所谓的打印,也是CPU先把数据取出来进行计算,然后才输出到屏幕上的,取数据的时候,是完整的取的。
CPU需要先把数据取出来,然后再根据特定的打印格式去输出!
编程题
1. 在字符串中找出连续最长的数字串
思路:
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
string str;
getline(cin,str);
//输入字符串
vector<string> v;
int max_len = 0;
auto start = str.begin();
while(start != str.end())
{
if(!isdigit(*start))
{
++start;
}
else
{
auto end = start;
int cur_len = 0;
while(end != str.end() && isdigit(*end))
{
//如果是数字,就++
++cur_len;
++end;
}
//走完此数字串,end指向非数字字符或者\0
//如果 此次的长度 大于最大长度,就清空再入v
if(cur_len > max_len)
{
max_len = cur_len; //更新最大长度
if(!v.empty())
{
v.clear();
}
v.push_back(string(start,end));
}
//如果相等,也入v
else if(cur_len == max_len)
{
v.push_back(string(start,end));
}
//然后更新start
start = end;
}
}
//遍历vector,输出
for(const auto& i : v)
{
cout << i;
}
cout <<","<<max_len << endl;
return 0;
}
2. 数组中超过一半的数字
1. 哈希
不推荐,因为空间复杂度O(N) 不满足要求,并且,数据范围不集中,太浪费了
2. 排序
先排序,那么如果存在众数,一定在中间,找出这个数
然后遍历数组,统计该数出现的次数
然后看是否满足 出现的次数大于数组长度一半
但是时间复杂度最少位 O(N*logN),而题目要求O(N)
3. 候选法★
如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数!
int m_v = 0; //记录候选人
int m_cnt = 0; //记录出现次数
遍历数组,如果m_cnt == 0 ,说明此时没有候选人,取当前的元素为候选人
下一个,如果等于 m_v,说明此候选人又出现一次,++m_cnt
如果不等于m_cnt,说明出现了一个竞争者,机会少一,所以--m_cnt。 (候选的和不候选的 抵消了)
这样遍历下来,
如果m_cnt为0,说明没有这样的数! 都一一抵消了!
如果最终m_cnt不为0 说明有一个数获胜,此时如果数组存在出现次数大于n/2的数字,那么这个数m_v一定是出现次数大于 n/2的数
所以还要遍历数组,看一下m_v是否出现了 n/2 以上的次数
## 但题目其实说了 不会存在无解的情况
## 但是我们需要知道,如果无解,需要额外判断一下!
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
int m_cnt = 0;
int m_v = 0;
for(auto i : numbers)
{
if(m_cnt == 0)
{
m_v = i;
++m_cnt;
}
else
{
if(i == m_v)
{
++m_cnt;
}
else
{
--m_cnt;
}
}
}
//如果没有这样的数,返回0
if(m_cnt == 0)
{
return 0;
}
else
{
//如果有一个数获胜,再遍历数组 查看该数是否出现n/2次以上
m_cnt = 0; //先赋值为0
for(auto i : numbers)
{
++m_cnt;
}
if(m_cnt > numbers.size()/2)
{
return m_v;
}
else
{
return 0;
}
}
return m_v;
}
};