跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 笔试刷题 Day 18:字符串压缩、TopK 与 01 背包

综述由AI生成三道 C++ 笔试算法题。第一题是字符串压缩,使用双指针统计字符出现次数并拼接结果。第二题是 TopK 问题,通过自定义比较器对 pair 排序,优先按甜度降序、酸度升序选取前 K 个。第三题是经典的 01 背包动态规划问题,提供了二维数组解法及空间优化后的一维数组解法,核心在于状态转移方程的选择与遍历顺序。

开源信徒发布于 2026/3/28更新于 2026/5/3025 浏览
C++ 笔试刷题 Day 18:字符串压缩、TopK 与 01 背包

一、压缩字符串

题目解析

题目给定一个字符 str,要求将字符串进行压缩。

压缩规则: 出现多次的字符压缩成 字符 + 数字;例如 aaa 压缩成 a3。如果字符值出现一次,1 不用写。

算法思路

这道题比较简单,直接模拟整个过程即可。

思路: 使用双指针遍历,统计字符和字符出现的次数。

  • i 固定一个字符,j 向后遍历找与 i 位置相同的字符。
  • 如果相同就继续向后遍历,直到 j 位置与 i 位置的字符不相同。
  • j 向后遍历结束,i 位置字符出现的次数为 j-i。
  • 如果 j-i > 1 就在结果字符串中加入出现的次数;等于 1 则不用加次数。

代码实现

class Solution {
public:
    string compressString(string param) {
        string ret;
        for (int i = 0; i < param.size(); ) {
            int j = i + 1;
            while (j < param.size() && param[j] == param[i]) j++;
            ret += param[i];
            if (j - i > 1) ret += to_string(j - i);
            i = j;
        }
        return ret;
    }
};

二、chika 和蜜柑

题目解析

chika 很喜欢吃蜜柑,每一个蜜柑有一定的甜度和酸度。 现在输入 n 表示蜜柑的个数,k 表示 chika 要吃 k 个蜜柑;然后依次输入每个蜜柑的酸度、每个蜜柑的甜度。 chika 想要甜度尽可能的大,如果存在甜度相等的情况,就让酸度尽可能小。 现在要我们求酸度和甜度(甜度尽可能大,酸度尽可能小)。

算法思路

对于这道题,是一道 TopK 问题。 TopK 问题简单来说就是在一堆数据中寻找较大或较小的 k 个数。 对于我们这道题来说,我们要甜度尽可能大,那就是找甜度较大的 k 个数;但是,在甜度相等的时候,要酸度尽可能小。 我们可以使用 pair<int, int> 类型来存储每一个蜜柑的甜度和酸度。 pair<int, int> 的默认比较大小的方式是:首先比较 first,first 大就大; 相等再看 , 大就大。 但是这里要求的比较方式是:先比较甜度,甜度大就大;甜度相等再看酸度,酸度要尽可能小。 所以我们需要自己实现一个可调用对象来比较两个 类型的对象。

first
second
second
pair<int, int>

比较方式: 如果 first 不相等,就比较 first;如果 first 相等比较 second。 这里实现排降序:

  • 如果 first 不相等,返回 a.first > b.first。
  • 如果 first 相等,比较 second 返回 a.second < b.second。 这样可调用对象返回的就是 a 是否大于 b,排序即为降序。

代码实现

这里可调用对象使用 lambda 表达式实现。

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

const int N = 2e5 + 10;
int n, k;
typedef pair<int, int> PII;
PII arr[N];

int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) cin >> arr[i].second;
    for (int i = 0; i < n; i++) cin >> arr[i].first;

    sort(arr, arr + n, [](PII& a, PII& b) {
        if (a.first != b.first) return a.first > b.first;
        else return a.second < b.second;
    });

    long long a = 0, b = 0;
    for (int i = 0; i < k; i++) {
        a += arr[i].first;
        b += arr[i].second;
    }
    cout << b << ' ' << a << endl;
    return 0;
}

三、01 背包

题目解析

这是一道经典的 01 背包问题。 题目给定一个 V 表示背包的体积、n 表示物品的个数、vw 数组。 其中 vw[i][0] 表示第 i 个物品的体积、vw[i][1] 表示第 i 个物品的重量。 最后让我们返回从 n 个物品中选择体积不超过 V 的物品的最大重量。

算法思路

对于背包问题的解题思路,就是动态规划(线性 DP)。

状态表示: dp[i][j]:表示在 i 个物品中选择体积不超过 j 的物品,这些物品重量的最大值。(背包容量为 j,从 i 个物品中选择时的最大重量)。

状态转移方程: 对于 i 位置的物品,可以选择这个物品,也可以不选择。

  • 如果选择 i 位置:dp[i][j] = dp[i-1][j-v[i]] + v[i](其中 v[i] 表示 i 位置物品的重量)。
  • 如果不选择 i 位置:dp[i][j] = dp[i-1][j]。

在填表时,当背包容量要大于物品 i 的体积,这时可以选择该物品(需要考虑是否选择);如果背包容量小于物品 i 的体积,就不能选择该物品(不需要考虑)。

空间优化: 可以使用一维 dp 表来解决。 在遍历 i 时,枚举在 i 个物品中选择体积不超过 j 的物品。 对于某一个物品,不选择它时的最大重量等于此时的 dp[j],选择它时的最大重量等于 dp[j - v[i]] + z[i](其中 z[i] 表示 i 物品的重量)。 即 dp[j] = max(dp[j], dp[j-v[i]] + z[i])。 注意需要从右往左填表,否则就会覆盖掉之前的数据。

代码实现

二维 DP 解法:

class Solution {
public:
    int dp[1001][1001] = {0};
    int knapsack(int V, int n, vector<vector<int>>& vw) {
        // write code here
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= V; j++) {
                if (vw[i - 1][0] <= j) {
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vw[i - 1][0]] + vw[i - 1][1]);
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return dp[n][V];
    }
};

空间优化(一维 DP):

class Solution {
public:
    int dp[1001] = {0};
    int knapsack(int V, int n, vector<vector<int>>& vw) {
        // write code here
        for (int i = 0; i < n; i++) {
            for (int j = V; j >= vw[i][0]; j--) {
                dp[j] = max(dp[j], dp[j - vw[i][0]] + vw[i][1]);
            }
        }
        return dp[V];
    }
};

目录

  1. 一、压缩字符串
  2. 题目解析
  3. 算法思路
  4. 代码实现
  5. 二、chika 和蜜柑
  6. 题目解析
  7. 算法思路
  8. 代码实现
  9. 三、01 背包
  10. 题目解析
  11. 算法思路
  12. 代码实现
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码
  • Docker 配置国内镜像源解决拉取镜像超时问题
  • 前端 Blob 文件格式原理与常见应用场景
  • Python 调用 TradingView-Screener 实现多维度选股策略
  • Python 依赖管理:requirements.txt 从安装到实战
  • WorkBuddy 深度体验:3 种核心模式与 Skill 技能包实战
  • VS Code 官方 Copilot 不支持自定义模型 API:替代方案与搜索用法
  • 使用 Python 和强化学习训练 MOBA 游戏 AI 原理
  • Midjourney AI 绘画核心指南:提示词与风格进阶
  • FPGA 光通信开发:Aurora 64B/66B 使用指南
  • LLM 大模型推理加速方案:vllm、fastllm、llama.cpp 使用指南与总结
  • Python 基于微信小程序的毕业设计选题管理系统
  • 算法模拟法解题实战
  • Writely 浏览器插件工作原理:AI 写作助手在网页编辑器中的实现
  • LangChain 前端流式输出实现指南
  • Linux 网络基础(一)
  • 微信小程序 WebView 组件使用及场景分析
  • Python asyncio 完全指南
  • LightRAG - 更快更便宜的 GraphRAG 技术详解
  • 基于 FPGA 的 CLAHE 自适应限制对比度直方图均衡算法硬件实现

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online