Day2 排序子序列、倒置字符串

news/2024/6/19 6:25:37 标签: c++, 开发语言

✨个人主页: 北 海
🎉所属专栏: C/C++相关题解
🎃操作环境: Visual Studio 2019 版本 16.11.17

成就一亿技术人


文章目录

  • 选择题
    • 1.字符串/C指针
    • 2.计算机组成原理
  • 编程题
    • 1.排序子序列
    • 2.倒置字符串


选择题

1.字符串/C指针

题目:下列叙述错误的是()

char acX[]="abc";
char acY[]={'a','b','c'};
const char *szX="abc";
const char *szY="abc";

选项:

  • A. acXacY 的内容可以修改
  • B. szXszY 指向同一个地址
  • C. acX 占用的内存空间比 acY 占用的大
  • D. szX 的内容修改后,szY 的内容也会被更改

分析:本题知识点为 字符与字符串+数组名与指针的区别+常量指针的特点,字符串由字符构成,并且会多出一个结束字符 '\0';数组中存储的数据位于 区,是可读可写的,而常量指针所指向的数据位于 常量区,只可被读取;同时因为 常量区 中相同的数据只会存在一份,因此不同的常量指针指向的对象为同一个

因为 数组中存储的数据位于 栈区,可读可写,所以 A 正确

常量区中的同一个数据只会存在一份,因此两个不同的常量指针指向同一个对象,地址自然相同,B 正确

在字符数相同的情况下,存储字符串所占空间比单纯存储字符大 1 字节,因此 C 正确

常量区中的数据不可被修改D 错误;假若通过某种特殊手段对其读写权限进行更改后,szX 的内容修改确实会影响 szY 内容,但这里只是普通场景,因此错误

注意: 直接打印常量指针 szXszY 时,会打印其所指向的内容,如果想查看指针值(地址)需要指定输出格式或进行转换

结果:D

图解

2.计算机组成原理

题目:在32位cpu上选择缺省对齐的情况下,有如下结构体定义:

struct A 
{
	unsigned a : 19;
	unsigned b : 11;
	unsigned c : 4;
	unsigned d : 29;
	char index;
};

sizeof(struct A) 的值为()

选项:

  • A. 9
  • B. 12
  • C. 16
  • D. 20

分析:本题知识点为 位段,相关知识可以查看这篇文章 《C语言进阶——自定义类型》位段 结构在存储数据时,会根据后面的大小(表示所需要的比特位)填入待开辟的空间中,假设当前空间无法容纳下一个成员,则会重新开辟空间进行存储,所有数据存储后,会进行 内存对齐

注:unsignedunsigned int 等价,都表示无符号整型

首先开辟 4 字节大小的空间(32 比特位),当成员 a 占用 19 比特位空间后,剩余 13 比特位

然后成员 b 紧接着 a 继续占用 11 比特位,此时 剩余 2 比特位

当成员 c 想占用 4 比特位时,发现 剩余的比特位(2 比特位)已经无法满足其需求了,于是编译器会重新开辟一块 4 字节大小的空间,将 c 存进去,此时新空间剩余 28 比特位,累计开辟了 8 字节空间

同理,当 d 想存储时,发现 剩余的比特位(28 比特位)也无法将自己完整的存储进去,于是编译器会再开辟 4 字节空间,将 d 进行存储,此时新空间剩余 3 比特位,累计开辟了 12 字节空间

最后虽然 index 只需 8 比特位(一个 char1 字节),但因 剩余比特位(3 比特位)无法存下,于是会新开辟 1 字节大小的空间,将 index 进行存储,现在已经共计开辟了 13 字节的空间

为了方便后续数据的读取,编译器会进行 内存对齐,将所占用的空间对齐至最大已开辟新空间(int)的整数倍,现在是占用了 13 字节,不是 int 的整数倍,因此会多开辟至 16 字节,确保 内存对齐

总的来说,struct A 中各成员的内存占用情况如下图所示:

图解

注意: 位段 在存储时本着 共用空间 的原则,将不同需求的成员放在同一块空间中,假若放不下,则会重新开辟新空间进行存储,位段 只有在所有成员都存储后,才会进行内存对齐

结果:C

结果


编程题

1.排序子序列

题目链接:排序子序列

题目

题目分析:现在有一个正整数数组 A,牛牛想要将其分割为 非递增非递减 子序列,最少可以分为几个序列;非递增 表示 递减中包含相等的情况非递减 则是 递增中包含相等的情况,题目给出的数组 A 有可能是 非有序 的,因此需要将其进行划分为子序列,本题的解题关键在于 对 非递增非递减 之间的切换的把握

  • 首先对整个数组 A 进行遍历
  • 假设 A[pos] < A[pos + 1] 说明此时即将进入 非递增 区间,可以将其走完(或者走到变成 非递减),此时获得一个 非递增 的子序列
  • 同理如果 A[pos] > A[pos + 1],则一样需要往后走,直到不符合规则,获得一个 非递减 的子序列
  • 假设是相等的情况,可以不用管,直接正常向后走一步即可

注意: 在向后走的过程中,可能出现越界问题,可以将数组 A 的空间多开辟一块空间,确保不会越界(因为题目明确其中的值为正整数,所以最后一块空间中的 0 值不会影响子序列)

结果

#include <iostream>
#include <vector>
using namespace std;

size_t getSubStrNum(const vector<int>& v, size_t n)
{
    int strNum = 0; //子序列数

    //遍历 v
    size_t pos = 0;
    while (pos < n)
    {
        if (v[pos] < v[pos + 1])
        {
            //进入非递减区域,开始向后走,直到不符合规则
            while (pos < n && v[pos] <= v[pos + 1])
                pos++;
            strNum++;
            pos++;
        }
        else if (v[pos] == v[pos + 1])
        {
            //相等时,可以忽略,直接向后走
            pos++;
        }
        else
        {
            //进入非递增区域,开始向后走,直到不符合规则
            while (pos < n && v[pos] >= v[pos + 1])
                pos++;
            strNum++;
            pos++;
        }
    }

    return strNum;
}

int main()
{
    int n = 0;  //输入的数据数
    while (cin >> n)
    {
        vector<int> A(n + 1);
        for (int i = 0; i < n; i++)
            cin >> A[i];    //将数据存入 vector 中
        size_t subStrNum = getSubStrNum(A, n); //获取可分割的子序列数
        cout << subStrNum << endl;
    }

    return 0;
}

注意:

  • 每次在成功获取(走完)一个子序列后,pos 需要向后移动一位,进入新的子序列判断
  • 在进行子序列获取(移动)时,需要注意越界问题,可以在开辟数组时,多开辟一块空间

结果

2.倒置字符串

题目链接:倒置字符串

题目

题目分析:将字符串倒置后,要确保每个单词的及标点符号的合理性,因此需要先将其整体倒置,然后再分别对每一个单词(含标点)进行倒置,这样就能达到题目要求

题目比较简单,先来看看 C++ 版本(可以用库函数和容器)

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string str;
    while (getline(cin, str))
    {
        //先将 str 整体倒置
        reverse(str.begin(), str.end());

        //再将每次单词及标点进行倒置
        auto begin = str.begin();
        auto end = str.begin();

        while (end != str.end())
        {
            while (end != str.end() && *end != ' ')
                end++;

            reverse(begin, end);
            
            if (end != str.end())
                ++end;

            begin = end;
        }

        cout << str << endl;
    }
    return 0;
}

再来看看 C语言 版本(需要自己写函数)

#include <stdio.h>
#include <string.h>
#include <assert.h>

void myReverse(char* str, int begin, int end)
{
    assert(str);

    //双指针交换
    while(begin < end)
    {
        char ch = str[begin];
        str[begin] = str[end - 1];
        str[end - 1] = ch;
        begin++;
        end--;
    }
}

int main() 
{
    char str[100] = { 0 };  //str 不超过 100
    while(gets(str))
    {
        int len = strlen(str);

        //先整体倒置
        myReverse(str, 0, len);

        //再逐个单词及标点进行倒置
        int begin = 0;
        int end = 0;
        while(end < len)
        {
            while(end < len && str[end] != ' ')
                end++;
            
            myReverse(str, begin, end);

            if(end < len)
                end++;
            
            begin = end;
        }

        printf("%s\n", str);
    }

    return 0;
}

可以看出 C 还是要高效一些

结果

注意: 在进行倒置时,需要注意边界问题,一般范围为 左闭右开

今天的选择题2中,需要重点回顾 位段 相关知识,如内存对齐;关于编程题1,需要想清楚子序列的获取判断逻辑,重点注意边界问题,编程题2也是如此


星辰大海

相关文章推荐

Day1 组队竞赛、删除公共字符

C++题解 | 逆波兰表达式相关

C语言题解 | 去重数组&&合并数组

C语言题解 | 消失的数字&轮转数组


http://www.niftyadmin.cn/n/333154.html

相关文章

技术面试的终极指南:助你取得成功的关键步骤

背景 技术面试是许多求职者最关键的一环&#xff0c;因为它评估了你在特定领域的知识和技能。无论你是刚毕业的大学应届生&#xff0c;还是有多年工作经验的职场老兵&#xff0c;准备充分是成功面试的关键。 这篇文章将提供一系列关键步骤&#xff0c;帮助你充分准备和展现自己…

使用thrift进行RPC通信(附c程序示例)

前言 为了实现不同语言的程序跨进程、跨主机通信&#xff0c;一般可以采用mq或rpc框架来实现。 对于异步通知的场景可以使用mq&#xff0c;如zeroMQ。 但对于某些实时性较强且同步的应用场景&#xff0c;使用成熟的rpc框架来实现也是一种比较更好的选择。 开源的rpc框架有很…

【EfficientDet】《EfficientDet:Scalable and Efficient Object Detection》

CVPR-2020 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method4.1 BiFPN4.2 EfficientDet 5 Experiments5.1 Datasets5.2 EfficientDet for Object Detection5.3 EfficientDet for Semantic Segmentation5.4 Ablation Study 6 Conclusio…

chatgpt赋能Python-openpyxl_批注

Openpyxl 批注简介 Openpyxl 是一个用于操作 Microsoft Excel 文件的 Python 库&#xff0c;它提供了许多方便的功能来读取、写入和修改 Excel 文件。其中一个功能是批注&#xff0c;可以在单元格中添加注释或提醒。 Openpyxl 批注的具体用途 Openpyxl 批注在 Excel 工作表中…

DPDK之l3fwd-power源码解析

DPDK之l3fwd-power源码解析 引言1 源码概述1.1 关键变量1.2 数据结构 2 源码解析2.1 LEGACY模式2.2 EMPTY_POLL模式2.3 TELEMETRY模式2.4 INTERRUPT模式2.5 PMD_MGMT模式 3 主要API3.1 CPU调频接口3.2 empty_poll电源管理接口3.3 pmd电源管理接口3.4 中断接口3.5 ip路由接口 引…

chatgpt赋能Python-numpy取出一列

用Numpy取出一列数据 在Python编程中&#xff0c;经常需要处理大量数据&#xff0c;而NumPy是一款专门用于处理数据的开源Python库&#xff0c;它提供了高性能的数组和矩阵计算功能&#xff0c;因此成为了Python科学计算领域的重要工具。在NumPy中&#xff0c;取出一列数据是常…

chatgpt赋能Python-libreoffice_python扩展

LibreOffice Python扩展: 提升办公效率的利器 如果你一直在寻找一种提高办公效率的方法&#xff0c;那么你肯定会喜欢LibreOffice Python扩展。作为LibreOffice的一个特性&#xff0c;它可以让你使用Python编写宏程序自动化你的日常办公任务。 什么是LibreOffice Python扩展&…

电压比较器

电压比较器&#xff1a; 应用一&#xff1a;过压&#xff0c;低压检测&#xff08;over and undervoltage detectors&#xff09; 如果Vin<Vs&#xff0c;则VoutVpullup。 如果Vin>Vs&#xff0c;则Vout0V。 应用二&#xff1a;窗口比较器&#xff08;window comparat…