【笔试刷题训练】day_03

选择题

在这里插入图片描述

二维数组的初始化,不同的语言有些不同,有些遗忘

在这里插入图片描述

这一题涉及到函数栈帧、大小端问题,值得思考一下
题目所给是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;
    }
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021狮子歌歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值