矩阵每一行各自乘上相同的数

这篇博客介绍了如何利用numpy的广播机制,简洁地实现矩阵与向量的乘法,特别是在计算tf-idf加权句向量时的应用。通过将词向量矩阵和tf-idf值向量相乘,一次性得到加权后的句向量,然后使用np.sum()求和,简化了计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

矩阵每一行各自乘上相同的数,满足 矩阵的行数=向量的维度 

试过用np.tile, np.reshape来解决但写的很麻烦,后面发现利用numpy的broadcast机制两行代码即可解决

import numpy as np

x = [[1, 1, 1], 
    [3, 3, 3], 
    [5, 5, 6]]
y = [1, 2, 3]
y = np.reshape(y, [-1, 1])
res = np.multiply(x, y)
print(res)

打印的结果为

[[ 1  1  1]
 [ 6  6  6]
 [15 15 18]]

本人是在计算tf-idf加权句向量的时候遇到的这个问题,将每个词的词向量拼成一个矩阵,然后对应的tf-idf值拼成向量,这样在计算加权的时候一次乘法即可求的结果,最后用np.sum()函数指定维度进行求和即可得到tf-idf加权的句向量

<think>嗯,这个问题看起来有点挑战性,不过让我慢慢来理清楚思路。首先题目是说有一个n行m列的矩阵,每个位置上的字代表该位置叠放的小正方体的量。要求计算这个几何体的三视图(正视图、俯视图、侧视图)各自的面积。然后用C++编程实现。 首先,我需要理解三视图的定义。正视图应该是从正面看过去的投影面积,俯视图是从上面看,侧视图可能是从侧面(比如右侧)看。每个视图的面积计算方式可能不同。 对于俯视图来说,不管每个位置叠了多少个正方体,只要至少有一个,俯视时就会覆盖一个单位面积。所以俯视图的面积其实就是矩阵中有多少个位置的值大于0。例如,如果矩阵是[[1,0],[2,3]],那么俯视图面积就是3,因为有三个位置有正方体。 接下来是正视图和侧视图。这两个视图需要考虑每一行或每一列中的最大值。比如正视图是从正面看,那么每一列中最高的那个正方体的高度决定了这一列在正视图中占据的高度,所有列的高度相加就是正视图的面积。同样,侧视图可能对应行中的最大值之和,或者要看具体是左视图还是右视图,但题目里说的侧视图可能指的是某一侧,比如右侧,所以可能需要取每行的最大值相加。 不过我需要确认侧视图的具体定义。假设侧视图是从右侧看,那么对于每一行来说,该行中的最大值决定了该行在侧视图中的高度,因此侧视图的面积就是各行最大值之和。 那具体来说,三视图的面积计算方式应该是: - 俯视图:矩阵中非零元素的量。 - 正视图:各列的最大值之和。 - 侧视图:各行的最大值之和。 比如,假设矩阵是: 1 2 3 4 5 6 那么正视图各列的最大值是4,5,6,和为15;侧视图各行的最大值是3和6,和为9;俯视图的非零元素目是6,所以三个面积分别是15,9,6。 但这里有个问题,题目中的侧视图到底是指左侧还是右侧?或者是否可能要考虑不同的方向?比如,正视图可能有前面和后面,侧视图可能有左和右。不过通常三视图指的是正视图(前)、俯视图、侧视图(右),所以这里侧视图可能取每行的最大值,即从右侧看的高度之和。 那编程步骤应该是: 1. 输入n和m。 2. 输入n行,每行m个整,存入二维组。 3. 计算俯视图面积:遍历所有元素,统计非零的量。 4. 计算正视图面积:对每一列,找出该列中的最大值,将所有列的最大值相加。 5. 计算侧视图面积:对每一行,找出该行中的最大值,将所有行的最大值相加。 6. 输出这三个面积。 但需要确认是否正确。比如,如果一个位置有多个正方体,比如高度为3,那么在正视图中,这一列的高度就是3,侧视图中所在行的最大值如果是3的话,也会被计算进去。而俯视图只要有至少一个正方体,就算一个单位面积。 这样看来,计算方式是对的。那现在的问题是如何用C++实现。 具体实现步骤: - 读取n和m。 - 读取n行,每行m个整,存储到二维组grid中。 - 俯视图面积:遍历grid,统计其中非零元素的个。 - 正视图面积:对每一列j(从0到m-1),遍历每一行i,找到该列的最大值,累加。 - 侧视图面积:对每一行i,找到该行的最大值,累加。 - 输出这三个面积。 比如输入样例: 2 3 1 2 3 4 5 6 俯视图面积:6(所有元素都非零) 正视图面积:max(1,4)=4,max(2,5)=5,max(3,6)=6 → 4+5+6=15 侧视图面积:max(1,2,3)=3,max(4,5,6)=6 →3+6=9 所以输出15 9 6? 或者题目中三视图的顺序可能不同,比如正视图、侧视图、俯视图的顺序?比如题目要求输出顺序可能需要注意,比如题目说三视图各自的面积,可能需要明确顺序。例如,是否按照正视图、俯视图、侧视图的顺序?或者原题的例子可能有不同的顺序? 但原题中的描述是“三视图各自面积为多少”,可能没有明确顺序,需要根据常规的视图顺序。一般来说,三视图指的是正视图、俯视图、侧视图,但具体顺序可能需要根据题目的例子来推断。不过题目中给出的例子可能没有,所以需要按照通常的理解。例如,可能正视图是前视图,侧视图是右视图,俯视图是顶视图。所以输出顺序可能应该是正视图、侧视图、俯视图?或者正视图、俯视图、侧视图? 或者题目中的例子中的输入输出可能需要确定顺序。例如,假设输入是n=1, m=1,值为1,则三个视图的面积都是1。所以需要明确输出顺序。 根据原题中的描述:“三视图各自面积为多少”,输入要求是输出三个,所以需要明确顺序。根据常规的三视图,可能正视图是前视图,侧视图是右视图,俯视图是顶视图,但具体编程题中可能需要确认。或者可能按照正视图、俯视图、侧视图的顺序输出。例如,假设在题目中,输入样例的输出顺序为正视图面积、侧视图面积、俯视图面积? 或者可能原题的测试用例要求输出顺序为正视图、侧视图、俯视图?或者可能是正视图、侧视图、俯视图? 这个问题需要根据题目中的例子或描述来确定。但用户提供的例子中没有具体的输入输出样例,所以可能需要根据常规判断。或者可能题目中的三视图指的是正视图、左视图、俯视图?但通常可能包括正视图(前)、侧视图(右)、俯视图(顶)。或者不同的标准可能有不同的顺序。 或者根据问题中的描述,“输入一行两个整n,m表示矩阵的行和列,n行每行m个整”,其中每个位置上的字是该位置叠放的正方体量。例如,行可能对应y轴,列对应x轴,那么正视图可能对应从正面(比如z轴方向)看,那么每个列的最大值在x轴上的投影,即正视图的每一列对应原矩阵中的列的最大值,行的最大值对应侧视图的行最大值。这样正视图的面积是各列最大值之和,侧视图是各行最大值之和,俯视图是有效格。 所以,假设输出顺序是正视图、侧视图、俯视图的面积。例如,在样例输入中,比如: 输入: 2 3 1 2 3 4 5 6 则正视图各列最大值是4,5,6 →15;侧视图各行最大值是3,6 →9;俯视图是6个非零→6。输出应该是15 9 6。 那编程时需要按这个顺序输出。 现在,如何实现这个? 代码框架: #include <iostream> using namespace std; int main() { int n, m; cin >> n >> m; int grid[n][m]; for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { cin >> grid[i][j]; } } // 俯视图面积:统计非零的目 int fu = 0; for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { if (grid[i][j] > 0) { fu++; } } } // 正视图面积:各列的最大值之和 int zheng = 0; for (int j=0; j<m; j++) { // 列循环 int max_col = 0; for (int i=0; i<n; i++) { if (grid[i][j] > max_col) { max_col = grid[i][j]; } } zheng += max_col; } // 侧视图面积:各行的最大值之和 int ce = 0; for (int i=0; i<n; i++) { int max_row = 0; for (int j=0; j<m; j++) { if (grid[i][j] > max_row) { max_row = grid[i][j]; } } ce += max_row; } cout << zheng << " " << ce << " " << fu << endl; return 0; } 但这里有一个问题,C++中二维组的维度必须是常量,除非使用动态组。所以当n和m是变量时,int grid[n][m]在标准C++中是不允许的。正确的方式应该用动态组或者vector。 比如,应该用vector<vector<int>> grid(n, vector<int>(m))来处理。 所以修改代码: #include <iostream> #include <vector> using namespace std; int main() { int n, m; cin >> n >> m; vector<vector<int>> grid(n, vector<int>(m)); for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { cin >> grid[i][j]; } } int fu = 0; for (auto &row : grid) { for (int val : row) { if (val > 0) { fu++; } } } int zheng = 0; for (int j=0; j<m; j++) { int max_col = 0; for (int i=0; i<n; i++) { max_col = max(max_col, grid[i][j]); } zheng += max_col; } int ce = 0; for (int i=0; i<n; i++) { int max_row = 0; for (int j=0; j<m; j++) { max_row = max(max_row, grid[i][j]); } ce += max_row; } cout << zheng << " " << ce << " " << fu << endl; return 0; } 这样应该可以正确处理。例如,对于输入: 3 3 1 0 2 3 4 0 0 1 5 俯视图的非零目是7(所有位置中0的有三个,所以3x3=9,减去2个0?需要计算每个位置是否大于0)。 正视图各列最大值是3(第一列)、4(第二列)、5(第三列)→3+4+5=12. 侧视图各行最大值是2,4,5 →2+4+5=11. 俯视图是7个非零。所以输出应为12 11 7. 这样代码应该正确。 现在,用户还提到“框架与上一题相同”,可能是指输入输出的方式,比如使用相同的结构。因此,这个代码应该可以满足要求。</think>### **分步解析** #### **步骤1:理解三视图面积计算规则** - **俯视图**:每个位置只要有正方体(量≥1)就贡献1面积,总面积为非零元素个。 - **正视图**:每列的最大高度之和(从正面看,每列的最高块决定该列的高度)。 - **侧视图**:每行的最大高度之和(从侧面看,每行的最高块决定该行的高度)。 --- #### **步骤2:输入处理** 1. 读取矩阵 `n` 和列 `m`。 2. 读取 `n` 行,每行 `m` 个整,表示每个位置的正方体量。 --- #### **步骤3:计算俯视图面积** 遍历所有元素,统计非零元素的个: ```cpp int fu = 0; for (auto &row : grid) { for (int val : row) { if (val > 0) fu++; } } ``` --- #### **步骤4:计算正视图面积** 遍历每一列,取每列的最大值并累加: ```cpp int zheng = 0; for (int j = 0; j < m; j++) { int max_col = 0; for (int i = 0; i < n; i++) { max_col = max(max_col, grid[i][j]); } zheng += max_col; } ``` --- #### **步骤5:计算侧视图面积** 遍历每一行,取每行的最大值并累加: ```cpp int ce = 0; for (int i = 0; i < n; i++) { int max_row = 0; for (int j = 0; j < m; j++) { max_row = max(max_row, grid[i][j]); } ce += max_row; } ``` --- #### **步骤6:输出结果** 按顺序输出正视图、侧视图、俯视图的面积: ```cpp cout << zheng << " " << ce << " " << fu << endl; ``` --- ### **完整代码实现** ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, m; cin >> n >> m; vector<vector<int>> grid(n, vector<int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> grid[i][j]; } } // 计算俯视图面积 int fu = 0; for (auto &row : grid) { for (int val : row) { if (val > 0) fu++; } } // 计算正视图面积 int zheng = 0; for (int j = 0; j < m; j++) { int max_col = 0; for (int i = 0; i < n; i++) { max_col = max(max_col, grid[i][j]); } zheng += max_col; } // 计算侧视图面积 int ce = 0; for (int i = 0; i < n; i++) { int max_row = 0; for (int j = 0; j < m; j++) { max_row = max(max_row, grid[i][j]); } ce += max_row; } cout << zheng << " " << ce << " " << fu << endl; return 0; } ``` --- ### **示例验证** **输入:** ``` 2 3 1 2 3 4 5 6 ``` **输出:** ``` 15 9 6 ``` - **正视图**:各列最大值为 `4, 5, 6`,和为 `15`。 - **侧视图**:各行最大值为 `3, 6`,和为 `9`。 - **俯视图**:非零元素共 `6` 个。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值