C++编译的若干问题

本文探讨了C++编程中类与成员函数的高级用法。首先介绍了如何正确处理跨文件依赖,避免编译错误;其次讲解了如何在派生类中显式指定保留基类成员函数的方法,确保函数不会被意外隐藏。


1. 在A.h文件中实现一个class A的成员函数A::func{...}, 用到了class B。如果class B在A.h中仅仅只是声明 class B;,则编译器会报错:A::func{...;  B b->foo(); ...} class B的定义找不到。  正确的做法是,将A::func() {...} 放在A.cpp中。


2. class A; class A1 : A。    如果class A 和 class A1 都定义了成员函数foo(),但两者签名不一样。为了不让class A1::foo()将class A::foo()隐藏掉(某些代码可能使用了A::foo(),隐藏会编译出错),在class A1中,需要有语句 using A::foo; 这样A::foo()与A1::foo(...)就能共存。


// 3. class A的成员函数foo() 有两个版本, const XXX * foo() const; 和 XXX * foo(); 

### C++ 实现方格取数问题的算法 #### 问题描述 在一个 \(m \times n\) 的棋盘中,每个方格包含一个正整数。目标是从这些方格中选取若干个数,使得所选的任意两个数所在的方格之间没有公共边(即它们既不相邻也不共享任何顶点)。最终求出所选数的最大总和。 此问题可以通过动态规划结合图染色的思想来解决[^1]。 --- #### 解决方案概述 由于题目要求选出的数对应的方格不能有公共边,这实际上是一个二分图划分问题。我们可以将棋盘视为一张无向图,其中每个节点代表一个方格,如果两个方格相邻则连接一条边。通过黑白染色的方式将棋盘划分为两部分:黑色区域和白色区域。这样可以保证同一颜色内的所有方格互不相邻。 接着利用动态规划计算两种情况下的最大值: - 只选择黑格子中的数值; - 只选择白格子中的数值; 最后返回两者之间的较大值作为结果。 --- #### 动态规划具体实现 下面给出完整的 C++ 实现代码: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 函数用于判断坐标 (x,y) 是否合法 bool isValid(int x, int y, int rows, int cols){ return x >=0 && x<rows && y>=0 && y<cols; } // 主函数实现 int maxNonAdjacentSum(const vector<vector<int>>& grid){ if(grid.empty() || grid[0].empty()) return 0; int m = grid.size(); int n = grid[0].size(); // 定义四种状态DP数组 // dp_black[i][j]: 黑色格子(i,j)被选时的最大值 // dp_white[i][j]: 白色格子(i,j)被选时的最大值 vector<vector<int>> dp_black(m, vector<int>(n, 0)); vector<vector<int>> dp_white(m, vector<int>(n, 0)); // 初始化第一个格子的状态 dp_black[0][0] = ((0+1)%2 == 0 ? grid[0][0] : 0); // 如果是黑色格子才计入 dp_white[0][0] = (((0+1)%2 != 0) ? grid[0][0] : 0); // 如果是白色格子才计入 // 遍历整个网格更新dp表 for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ if(!isValid(i-1,j,m,n)){ dp_black[i][j] += dp_black[i][j]; dp_white[i][j] += dp_white[i][j]; } else{ dp_black[i][j] = max(dp_black[i-1][j], dp_white[i-1][j]); dp_white[i][j] = max(dp_black[i-1][j], dp_white[i-1][j]); } if(isValid(i,j-1,m,n)){ dp_black[i][j] = max(dp_black[i][j], max(dp_black[i][j-1], dp_white[i][j-1])); dp_white[i][j] = max(dp_white[i][j], max(dp_black[i][j-1], dp_white[i][j-1])); } // 加入当前格子贡献 if((i+j)%2==0){ // 黑色格子 dp_black[i][j] += grid[i][j]; } else{ // 白色格子 dp_white[i][j] += grid[i][j]; } } } // 返回最后一行一列的最大值 return max(dp_black[m-1][n-1], dp_white[m-1][n-1]); } int main(){ // 示例测试用例 vector<vector<int>> grid = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; cout << "Max Non Adjacent Sum is: " << maxNonAdjacentSum(grid) << endl; return 0; } ``` --- #### 关键点解析 1. **合法性检查** 使用 `isValid` 方法验证索引是否越界,从而安全访问矩阵元素[^1]。 2. **动态转移逻辑** 对于每一个位置 `(i,j)` ,其可能来源于上方或左方的位置,并且需区分该位置属于哪种颜色(黑/白)再决定加入哪个集合[^1]。 3. **初始化处理** 特殊对待初始单元格 `[0][0]` 的赋值操作,因为它是唯一不需要依赖其他前驱结点就能直接确定价值的地方[^1]。 --- #### 性能分析 - **时间复杂度**: 整体遍历了一次二维表格,所以时间复杂度为 O(M*N)[^1]。 - **空间复杂度**: 创建了一个同样规模的辅助存储结构用来保存中间过程的数据,因此空间复杂度也是 O(M*N)[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值