当前位置: 首页 > news >正文

从零开始的CPP(36)——操作Excel

现有一个Excel A1.csv。

其表格第一列为:生物样本的名称;其他列为:生物样本的含量。表格第一行第一列是空格,第一行其他列为:受试者名称。

需求

如下:设计一个程序,可以指定受试者名称(某列),对该列所有生物样本含量进行排序,保留含量前X名的生物样本,其余生物样本含量合并,命名为others。

设计思路:

1.如何根据受试者名称(第一行),读取csv中指定某列数据?

vector<string> getRownames() {ifstream file("A1.csv");string line;string rowname;vector<string> rownames;getline(file, line);for (int i = 0; i < line.length();) {if (line[i] == ',') {rowname = line.substr(0, i);rownames.push_back(rowname);line = line.substr(i + 1, line.length());i = 0;}else i++;}for (auto i : rownames) {cout << i << " ";}return rownames;
}

通过这段代码,就可以得到一个储存每列名称的vector了。

int findRowname(vector<string> rownames,string aim) {for (int i = 0; i < rownames.size(); i++) {if (rownames[i] == aim) {return i;}}
}

 通过这段代码,就可以得到目标受试者所在列了。

2.如何获得目标受试者所在列的数据及其对应样本名称?

vector<pair<string, double>> getNameAndData(int row) {vector<pair<string, double>> NameAndData;ifstream file("A1.csv");string line;string rowdata;double value;getline(file, line);while (getline(file, line)) {vector<string> rowdatas;for (int i = 0; i < line.length();) {if (line[i] == ',') {rowdata = line.substr(0, i);rowdatas.push_back(rowdata);line = line.substr(i + 1, line.length());i = 0;}else i++;}            value = stod(rowdatas[row]);NameAndData.push_back({ rowdatas[0], value });}for (auto i : NameAndData) {cout << i.first << " " << i.second << endl;}return NameAndData;
}

循环读取文件每一行,把每一行都存进vector,找到vector的0列(样本名)与row列(受试者所在列),将其pair,存入新vector。

这里有代码重复了,就是从line转换为vector的代码,可以将其封装。

void split(string line, vector<string>& linedatas) {string linedata;for (int i = 0; i < line.length();) {if (line[i] == ',') {linedata = line.substr(0, i);linedatas.push_back(linedata);line = line.substr(i + 1, line.length());i = 0;}else i++;}return;
}

需要时直接传入line和vector就可以啦。

3. 排序,并保留前X行,剩余行合并为others

复习了lambda表达式与sort函数结合的用法

vector<pair<string, double>> getNewNameAndData(vector<pair<string, double>> NameAndData,int reserve) {sort(NameAndData.begin(), NameAndData.end(), [](const auto& a, const auto& b) {return a.second > b.second;});vector<pair<string, double>> NewNameAndData(reserve + 1);for (int i = 0; i < reserve; i++) {NewNameAndData[i] = NameAndData[i];}double reservesum = 0;for (int i = reserve; i < NameAndData.size(); i++) {reservesum = reservesum + NameAndData[i].second;}NewNameAndData[reserve] = { "Others",reservesum };for (auto i : NewNameAndData) {cout << i.first << " " << i.second << endl;}return NewNameAndData;
}

 4.将new vector写入新文件

void getNewCsv(vector<pair<string, double>> NewNameAndData,int row) {ofstream file("newA.csv");ifstream file1("A1.csv");string line;getline(file1, line);vector<string> data0;split(line, data0);file << data0[0] << "," << data0[row] << endl;for (int i = 0; i < NewNameAndData.size(); i++) {file << NewNameAndData[i].first << "," << NewNameAndData[i].second << endl;}return;
}

5.完整代码

#include <iostream>
#include <fstream>
#include <sstream>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
class Solution {
public:vector<string> getRownames() {ifstream file("A1.csv");string line;string rowname;vector<string> rownames;getline(file, line);split(line, rownames);/*for (auto i : rownames) {cout << i << " ";}*/return rownames;}int findRowname(vector<string> rownames,string aim) {for (int i = 0; i < rownames.size(); i++) {if (rownames[i] == aim) {return i;}}return 0;}vector<pair<string, double>> getNameAndData(int row) {vector<pair<string, double>> NameAndData;ifstream file("A1.csv");string line;string rowdata;double value;getline(file, line);while (getline(file, line)) {vector<string> rowdatas;split(line, rowdatas);value = stod(rowdatas[row]);NameAndData.push_back({ rowdatas[0], value });}/*for (auto i : NameAndData) {cout << i.first << " " << i.second << endl;}*/return NameAndData;}vector<pair<string, double>> getNewNameAndData(vector<pair<string, double>> NameAndData,int reserve) {sort(NameAndData.begin(), NameAndData.end(), [](const auto& a, const auto& b) {return a.second > b.second;});vector<pair<string, double>> NewNameAndData(reserve + 1);for (int i = 0; i < reserve; i++) {NewNameAndData[i] = NameAndData[i];}double reservesum = 0;for (int i = reserve; i < NameAndData.size(); i++) {reservesum = reservesum + NameAndData[i].second;}NewNameAndData[reserve] = { "Others",reservesum };/*for (auto i : NewNameAndData) {cout << i.first << " " << i.second << endl;}*/return NewNameAndData;}void getNewCsv(vector<pair<string, double>> NewNameAndData,int row,string aim, int reverse) {stringstream ss;ss << reverse;string s1 = ss.str();string str = aim + "_"+s1+"_newA.csv";ofstream file(str);ifstream file1("A1.csv");string line;getline(file1, line);vector<string> data0;split(line, data0);file << data0[0] << "," << data0[row] << endl;for (int i = 0; i < NewNameAndData.size(); i++) {file << NewNameAndData[i].first << "," << NewNameAndData[i].second << endl;}cout << "文件已经保存在"<< str <<"中。";return;}private:void split(string line, vector<string>& linedatas) {string linedata;for (int i = 0; i < line.length();) {if (line[i] == ',') {linedata = line.substr(0, i);linedatas.push_back(linedata);line = line.substr(i + 1, line.length());i = 0;}else i++;}return;}
};int main()
{Solution solution;vector<string> rownames=solution.getRownames();// 用户输入目标名string aim;cout << "请输入目标名: ";cin >> aim;int row=solution.findRowname(rownames, aim);//cout << row;vector<pair<string, double>> NameAndData = solution.getNameAndData(row);// 用户输入保留行数int reverse;cout << "请输入保留行数: ";cin >> reverse;vector<pair<string, double>> NewNameAndData = solution.getNewNameAndData(NameAndData, reverse);solution.getNewCsv(NewNameAndData,row,aim,reverse);return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JS【详解】对象的内部属性 vs 内部方法
  • 【Android Studio】修改项目名称can‘t rename root module解决办法
  • 【Python随笔】比PyQt5更先进的pyside6安装和使用方法
  • 【使用Python和ADB过滤与处理Android包名】
  • SAAMDSSA-系统架构师(五十一)
  • Go开发后端和Vue3开发前端的前后端分离框架中自己手戳一个OA流程审批、工作流引擎给新时代一个漂亮便捷的工作流引擎
  • 验证码案例
  • UE中的运行时Mesh - 学习笔记
  • day16
  • Nginx系列-Nginx Location匹配规则
  • 【鸿蒙学习】Stage模型与FA模型的对比与应用选择
  • Spring Boot 3.x Rest API最佳实践之统一响应结构
  • 作为硬件工程师和射频工程师必备的射频前端冷知识
  • 提升前端性能的JavaScript技巧
  • 异步调用实践:Async,Future, TaskExecutor、EventListener
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Angular数据绑定机制
  • input的行数自动增减
  • JavaScript新鲜事·第5期
  • php的插入排序,通过双层for循环
  • python docx文档转html页面
  • SAP云平台里Global Account和Sub Account的关系
  • scala基础语法(二)
  • SOFAMosn配置模型
  • SpingCloudBus整合RabbitMQ
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 微信小程序设置上一页数据
  • 温故知新之javascript面向对象
  • 问题之ssh中Host key verification failed的解决
  • 新手搭建网站的主要流程
  • Java总结 - String - 这篇请使劲喷我
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • ### RabbitMQ五种工作模式:
  • #13 yum、编译安装与sed命令的使用
  • #565. 查找之大编号
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (6)STL算法之转换
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (二十四)Flask之flask-session组件
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (九)One-Wire总线-DS18B20
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (转)我也是一只IT小小鸟
  • **PHP二维数组遍历时同时赋值
  • ../depcomp: line 571: exec: g++: not found
  • .NET 5.0正式发布,有什么功能特性(翻译)