C/C++將切片資料列表轉換為二維陣列形式
阿新 • • 發佈:2022-03-16
Slice2Matrix
本文件將以切片資料為例介紹讀入文字格式資料,並將一維屬性值寫為二維陣列的過程。
實際工區中的切片常常是不規則的,因此在將其轉換為二維陣列的過程中,需將切片填充為一個規則的矩形。
需要用到的檔案:
1-4 SliceData IO.md中建立的標頭檔案SliceDataIO.h與C++檔案SliceDataIO.cpp;
新建標頭檔案SliceDataIO.h與C++檔案SliceDataIO.cpp,以及主函式main.cpp。
1 編寫標頭檔案SliceDataMatrix.h
1.1 程式描述、呼叫、宣告、定義
/********************************************************************** * Copyright(C) 2018,Company All Rights Reserved * * @file : SliceDataMatrix.cpp * * @brief : 實現切片資料向二維陣列的轉換 * * @version : 1.0 * * @author : Fan XinRan * * @date : 2022/2/8 星期二 * * Others : **********************************************************************/ #pragma once #include"SliceDataIO.h" //SliceDataIO.h中包含了需要的標準庫,全域性常量等
1.2 宣告最大、最小值結構體
此結構體用於存放最大/最小 Line/CDP的值及索引。
typedef struct MaxminResultInt{
int value;
int index;
} MaxminResultInt;
1.3 宣告SliceDataMatrix類
class SliceDataMatrix{ public: SliceDataMatrix(); //建構函式 ~SliceDataMatrix(); //解構函式 bool setData(SliceDataIO *datainput,int incLine,int incCDP); // set()方法 bool writeData(float **dataouput,const char *filenameOutput); // 寫入方法 float **getTimeMatrix(); //在實際應用時,通常需要的是Time和Value這兩個屬性 float **getValueMatrix(); private: int _nline; // 宣告:匯流排數 int _ncdp; // 總道數 int _IncLine; // 線取樣間隔 int _IncCDP; // 道取樣間隔 int _maxLineIndex; // 宣告: 最大線號 int _minLineIndex; // 最小線號 int _maxCDPIndex; // 最大道號 int _minCDPIndex; // 最小道號 int **_sliceIndexdataMatrix; // 宣告: 1 切片號二維陣列 int **_lineIndexMatrix; // 2 線號... int **_cdpIndexMatrix; // 3 道號... float **_Xmatrix; // 4 X座標... float **_Ymatrix; // 5 Y座標... float **_TimeMatrix; // 6 時間... float **_ValueMatrix; // 7 屬性值... bool **_flagMatrix; // 標識矩陣,用於標記該點是否有值 MaxminResultInt _maxminInt(int *dataInput, int n, bool flag); // 新建一個存放最大最小值的結構體物件 };
完整程式碼
/********************************************************************** * Copyright(C) 2018,Company All Rights Reserved * * @file : SliceDataMatrix.cpp * * @brief : 實現切片資料向二維陣列的轉換 * * @version : 1.0 * * @author : Fan XinRan * * @date : 2022/2/8 星期二 * * Others : **********************************************************************/ #pragma once #include"SliceDataIO.h" //SliceDataIO.h中包含了需要的標準庫,全域性常量等 typedef struct MaxminResultInt{ int value; int index; } MaxminResultInt; class SliceDataMatrix{ public: SliceDataMatrix(); ~SliceDataMatrix(); bool setData(SliceDataIO *datainput,int incLine,int incCDP); bool writeData(float **dataouput,const char *filenameOutput); float **getTimeMatrix(); float **getValueMatrix(); private: int _nline; int _ncdp; int _IncLine; int _IncCDP; int _maxLineIndex; int _minLineIndex; int _maxCDPIndex; int _minCDPIndex; int **_sliceIndexdataMatrix; int **_lineIndexMatrix; int **_cdpIndexMatrix; float **_Xmatrix; float **_Ymatrix; float **_TimeMatrix; float **_ValueMatrix; bool **_flagMatrix; MaxminResultInt _maxminInt(int *dataInput, int n, bool flag); };
2 編寫C++檔案SliceDataMatrix.cpp
2.1 定義建構函式與解構函式
SliceDataMatrix::SliceDataMatrix(){
this->_IncCDP = 0; // 定義取樣間隔和匯流排、道數
this->_IncLine = 0;
this->_ncdp = 0;
this->_nline = 0;
this->_minCDPIndex = 0; // 定義最大||最小 線號||道號
this->_maxCDPIndex = 0;
this->_minLineIndex = 0;
this->_maxLineIndex = 0;
this->_sliceIndexdataMatrix = NULL; // 定義slice相關的Matrix
this->_cdpIndexMatrix = NULL;
this->_lineIndexMatrix = NULL;
this->_TimeMatrix = NULL;
this->_ValueMatrix = NULL;
this->_Xmatrix = NULL;
this->_Ymatrix = NULL;
this->_flagMatrix = NULL; // 定義標識矩陣
}
// 解構函式
SliceDataMatrix::~SliceDataMatrix(){
if(this->_sliceIndexdataMatrix!=NULL){
free2int(_sliceIndexdataMatrix);
this->_sliceIndexdataMatrix = NULL;
}
if(this->_cdpIndexMatrix!=NULL){
free2int(_cdpIndexMatrix);
this->_cdpIndexMatrix = NULL;
}
if (this->_lineIndexMatrix != NULL) {
free2int(_lineIndexMatrix);
this->_lineIndexMatrix = NULL;
}
if (this->_Xmatrix != NULL) {
free2float(_Xmatrix);
this->_Xmatrix = NULL;
}
if (this->_Ymatrix != NULL) {
free2float(_Ymatrix);
this->_Ymatrix = NULL;
}
if (this->_TimeMatrix != NULL) {
free2float(_TimeMatrix);
this->_TimeMatrix = NULL;
}
if (this->_ValueMatrix != NULL) {
free2float(_ValueMatrix);
this->_ValueMatrix = NULL;
}
if (this->_flagMatrix != NULL) {
free2bool(_flagMatrix);
this->_flagMatrix = NULL;
}
}
2.2 定義方法函式
(1) set()方法
bool SliceDataMatrix::setData(SliceDataIO *datainput, int incLine, int incCDP){
// 此時輸入為SliceDataIO類物件
if(datainput==NULL){ // 判空
return false;
}
if((incLine<0)||(incCDP<0)){ // 判定傳入的取樣間隔是否合法
return false;
}
// 通過SliceDataIO類中的get()方法獲取基礎資料...
int *slice = datainput->getSliceIndex(); // 切片號
int *lineIndex = datainput->getLineIndex(); // 線號
int *cdpIndex = datainput->getCDPIndex(); // 道號
float *X = datainput->getX(); // X座標
float *Y = datainput->getY(); // Y座標
float *time = datainput->getTime(); // time值
float *value = datainput->getValue(); // value值
int nsample = datainput->getSampleNum(); // nsample取樣點
int index_Xtemp = 0; // 線、道號在陣列中的重新定位
int index_Ytemp = 0;
MaxminResultInt maxline; // 針對切片4個角點,新建四個結構體
MaxminResultInt maxcdp;
MaxminResultInt minline;
MaxminResultInt mincdp;
maxline = this->_maxminInt(lineIndex, nsample, true); // 計算出最大/最小的值、索引
maxcdp = this->_maxminInt(cdpIndex, nsample, true);
minline= this->_maxminInt(lineIndex, nsample, false);
mincdp= this->_maxminInt(cdpIndex, nsample, false);
this->_maxCDPIndex = maxcdp.value; // 存為當前類物件的屬性
this->_minCDPIndex = mincdp.value;
this->_maxLineIndex = maxline.index;
this->_minLineIndex = minline.index;
this->_IncCDP = incCDP; // 賦值
this->_IncLine = incLine;
this->_ncdp = (this->_maxCDPIndex - this->_minCDPIndex) / (this->_IncCDP) + 1; // 計算線數、道數
this->_nline = (this->_maxLineIndex-this->_minLineIndex)/ (this->_IncLine) + 1;
// alloc2為各變數分配二維陣列
// alloc2int、alloc2float與alloc2bool相似,均由alloc2衍生,而alloc2()返回一個void **ptr
this->_sliceIndexdataMatrix = alloc2int(this->_ncdp,this->_nline);
this->_cdpIndexMatrix = alloc2int(this->_ncdp, this->_nline);
this->_lineIndexMatrix= alloc2int(this->_ncdp, this->_nline);
this->_Xmatrix= alloc2float(this->_ncdp, this->_nline);
this->_Ymatrix = alloc2float(this->_ncdp, this->_nline);
this->_TimeMatrix= alloc2float(this->_ncdp, this->_nline);
this->_ValueMatrix= alloc2float(this->_ncdp, this->_nline);
this->_flagMatrix = alloc2bool(this->_ncdp, this->_nline); // flagMatrix為bool型
// 初始化
memset(this->_sliceIndexdataMatrix[0],0,(_ncdp)*(_nline)*sizeof(int));
memset(this->_cdpIndexMatrix[0], 0, (_ncdp)*(_nline) * sizeof(int));
memset(this->_lineIndexMatrix[0], 0, (_ncdp)*(_nline) * sizeof(int));
memset(this->_Xmatrix[0], 0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_Ymatrix[0],0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_TimeMatrix[0], 0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_ValueMatrix[0],0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_flagMatrix[0],0, (_ncdp)*(_nline) * sizeof(bool));
// 遍歷取樣點
for(int isample = 0; isample < nsample;isample++){
// 以左上角(cdp[0],line[0])為起點(0,0)換算相對索引
index_Xtemp = (cdpIndex[isample]-_minCDPIndex)/ _IncCDP;
index_Ytemp= (lineIndex[isample] - _minLineIndex) / _IncLine;
// 如果這個點落在劃定的矩形陣列內
if((index_Xtemp>=0)&&(index_Xtemp<_ncdp)&&(index_Ytemp>=0)&&(index_Ytemp<_nline)){
// 在相應的Matrix上填入該點資料
this->_sliceIndexdataMatrix[index_Ytemp][index_Xtemp] = slice[isample];
this->_cdpIndexMatrix[index_Ytemp][index_Xtemp] = cdpIndex[isample];
this->_lineIndexMatrix[index_Ytemp][index_Xtemp] = lineIndex[isample];
this->_Xmatrix[index_Ytemp][index_Xtemp] = X[isample];
this->_Ymatrix[index_Ytemp][index_Xtemp] = Y[isample];
this->_TimeMatrix[index_Ytemp][index_Xtemp] = time[isample];
this->_ValueMatrix[index_Ytemp][index_Xtemp] = value[isample];
this->_flagMatrix[index_Ytemp][index_Xtemp] = true; // true--->data exist
}//end if((index_Xtemp>=0)&&(index_Xtemp<_ncdp)&&(index_Ytemp>=0)&&(index_Ytemp<_nline))
}//end for(int isample = 0; isample < nsample;isample++)
return true;
}
(2) 求最大、最小座標
MaxminResultInt SliceDataMatrix::_maxminInt(int *dataInput, int n, bool flag){
// 輸入為一個
int value=dataInput[0];
int index=0;
MaxminResultInt maxmin;
if(flag==true){
for(int i= 0; i<n; i++){
if(dataInput[i] >value){
value = dataInput[i];
index = i;
}//end if(dataInput[i] >= value)
}//end for(int i= 0; i<n; i++)
}else{
for (int i = 0; i < n; i++) {
if (dataInput[i] < value) {
value = dataInput[i];
index = i;
}//end if(dataInput[i] >= value)
}//end for(int i= 0; i<n; i++)
}//end if(flag==true)
maxmin.value = value;
maxmin.index = index;
return maxmin;
}
(3) get()方法
float** SliceDataMatrix::getTimeMatrix(){
return this->_TimeMatrix;
}
float** SliceDataMatrix::getValueMatrix(){
return this->_ValueMatrix;
}
2.3 定義寫入函式
在這個複製切片的任務中,並未用到寫入函式,此步驟可忽略
bool SliceDataMatrix::writeData(float **dataouput, const char *filenameOutput){
int nx = 0;
int ny = 0;
return true;
}
完整程式碼
#include "SliceDataMatrix.h"
SliceDataMatrix::SliceDataMatrix(){ // 建構函式
this->_IncCDP = 0; // 取樣間隔
this->_IncLine = 0;
this->_ncdp = 0; // 匯流排、道數
this->_nline = 0;
this->_minCDPIndex = 0;
this->_maxCDPIndex = 0;
this->_minLineIndex = 0;
this->_maxLineIndex = 0;
this->_sliceIndexdataMatrix = NULL; // 切片屬性的二維陣列
this->_cdpIndexMatrix = NULL;
this->_lineIndexMatrix = NULL;
this->_TimeMatrix = NULL;
this->_ValueMatrix = NULL;
this->_Xmatrix = NULL;
this->_Ymatrix = NULL;
this->_flagMatrix = NULL; // 標識矩陣
}
SliceDataMatrix::~SliceDataMatrix(){ // 解構函式
if(this->_sliceIndexdataMatrix!=NULL){
free2int(_sliceIndexdataMatrix);
this->_sliceIndexdataMatrix = NULL;
}
if(this->_cdpIndexMatrix!=NULL){
free2int(_cdpIndexMatrix);
this->_cdpIndexMatrix = NULL;
}
if (this->_lineIndexMatrix != NULL) {
free2int(_lineIndexMatrix);
this->_lineIndexMatrix = NULL;
}
if (this->_Xmatrix != NULL) {
free2float(_Xmatrix);
this->_Xmatrix = NULL;
}
if (this->_Ymatrix != NULL) {
free2float(_Ymatrix);
this->_Ymatrix = NULL;
}
if (this->_TimeMatrix != NULL) {
free2float(_TimeMatrix);
this->_TimeMatrix = NULL;
}
if (this->_ValueMatrix != NULL) {
free2float(_ValueMatrix);
this->_ValueMatrix = NULL;
}
if (this->_flagMatrix != NULL) {
free2bool(_flagMatrix);
this->_flagMatrix = NULL;
}
}
// set method
bool SliceDataMatrix::setData(SliceDataIO *datainput, int incLine, int incCDP){
if(datainput==NULL){ // 判空
return false;
}
if((incLine<0)||(incCDP<0)){ // 判定輸入的取樣間隔是否合法
return false;
}
int *slice = datainput->getSliceIndex(); // 通過SliceDataIO類中的get()方法獲取各類屬性值
int *lineIndex = datainput->getLineIndex();
int *cdpIndex = datainput->getCDPIndex();
float *X = datainput->getX();
float *Y = datainput->getY();
float *time = datainput->getTime();
float *value = datainput->getValue();
int nsample = datainput->getSampleNum();
int index_Xtemp = 0; // 線、道號在陣列中的重新定位
int index_Ytemp = 0;
MaxminResultInt maxline; // 針對切片的4個角點,新建四個結構體變數
MaxminResultInt maxcdp;
MaxminResultInt minline;
MaxminResultInt mincdp;
maxline = this->_maxminInt(lineIndex, nsample, true); // 計算出最大/最小的值、索引
maxcdp = this->_maxminInt(cdpIndex, nsample, true);
minline= this->_maxminInt(lineIndex, nsample, false);
mincdp= this->_maxminInt(cdpIndex, nsample, false);
this->_maxCDPIndex = maxcdp.value; //存到當前類物件
this->_minCDPIndex = mincdp.value;
this->_maxLineIndex = maxline.value;
this->_minLineIndex = minline.value;
this->_IncCDP = incCDP;
this->_IncLine = incLine;
this->_ncdp = (this->_maxCDPIndex - this->_minCDPIndex) / (this->_IncCDP) + 1; // 計算匯流排、道數
this->_nline = (this->_maxLineIndex-this->_minLineIndex)/ (this->_IncLine) + 1;
// alloc2為各屬性分配二維空間
this->_sliceIndexdataMatrix = alloc2int(this->_ncdp,this->_nline);
this->_cdpIndexMatrix = alloc2int(this->_ncdp, this->_nline);
this->_lineIndexMatrix= alloc2int(this->_ncdp, this->_nline);
this->_Xmatrix= alloc2float(this->_ncdp, this->_nline);
this->_Ymatrix = alloc2float(this->_ncdp, this->_nline);
this->_TimeMatrix= alloc2float(this->_ncdp, this->_nline);
this->_ValueMatrix= alloc2float(this->_ncdp, this->_nline);
this->_flagMatrix = alloc2bool(this->_ncdp, this->_nline);
// 初始化
memset(this->_sliceIndexdataMatrix[0],0,(_ncdp)*(_nline)*sizeof(int));
memset(this->_cdpIndexMatrix[0], 0, (_ncdp)*(_nline) * sizeof(int));
memset(this->_lineIndexMatrix[0], 0, (_ncdp)*(_nline) * sizeof(int));
memset(this->_Xmatrix[0], 0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_Ymatrix[0],0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_TimeMatrix[0], 0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_ValueMatrix[0],0, (_ncdp)*(_nline) * sizeof(float));
memset(this->_flagMatrix[0],0, (_ncdp)*(_nline) * sizeof(bool));
for(int isample = 0; isample < nsample;isample++){
index_Xtemp = (cdpIndex[isample]-_minCDPIndex)/ _IncCDP; // 以左上角為(0,0)轉換後的索引
index_Ytemp= (lineIndex[isample] - _minLineIndex) / _IncLine;
if((index_Xtemp>=0)&&(index_Xtemp<_ncdp)&&(index_Ytemp>=0)&&(index_Ytemp<_nline)){ // 如果該點落在矩形陣列範圍內
this->_sliceIndexdataMatrix[index_Ytemp][index_Xtemp] = slice[isample]; // 相應的Matrix中填入該點資料
this->_cdpIndexMatrix[index_Ytemp][index_Xtemp] = cdpIndex[isample];
this->_lineIndexMatrix[index_Ytemp][index_Xtemp] = lineIndex[isample];
this->_Xmatrix[index_Ytemp][index_Xtemp] = X[isample];
this->_Ymatrix[index_Ytemp][index_Xtemp] = Y[isample];
this->_TimeMatrix[index_Ytemp][index_Xtemp] = time[isample];
this->_ValueMatrix[index_Ytemp][index_Xtemp] = value[isample];
this->_flagMatrix[index_Ytemp][index_Xtemp] = true; // true--->data exist
}//end if((index_Xtemp>=0)&&(index_Xtemp<_ncdp)&&(index_Ytemp>=0)&&(index_Ytemp<_nline))
}//end for(int isample = 0; isample < nsample;isample++)
return true;
}
// 計算切片角點的最大、最小 Line/CDP
MaxminResultInt SliceDataMatrix::_maxminInt(int *dataInput, int n, bool flag){
int value=dataInput[0];
int index=0;
MaxminResultInt maxmin;
if(flag==true){ // flag=true---> max value/index
for(int i= 0; i<n; i++){
if(dataInput[i] >value){
value = dataInput[i];
index = i;
}//end if(dataInput[i] >= value)
}//end for(int i= 0; i<n; i++)
}else{ // else---> min value/index
for (int i = 0; i < n; i++) {
if (dataInput[i] < value) {
value = dataInput[i];
index = i;
}//end if(dataInput[i] >= value)
}//end for(int i= 0; i<n; i++)
}//end if(flag==true)
maxmin.value = value;
maxmin.index = index;
return maxmin;
}
// -------------------get()方法------------------
float** SliceDataMatrix::getTimeMatrix(){
return this->_TimeMatrix;
}
float** SliceDataMatrix::getValueMatrix(){
return this->_ValueMatrix;
}
bool** SliceDataMatrix::getFlagMatrix(){
return this->_flagMatrix;
}
int SliceDataMatrix::getNumLine(){
return this->_nline;
}
int SliceDataMatrix::getNumCdp(){
return this->_ncdp;
}
// write data to outputfile
bool SliceDataMatrix::writeData(float **dataouput, const char *filenameOutput){
int nx = 0;
int ny = 0;
return true;
}
3 編寫主函式main.cpp
#include"SliceDataIO.h"
int main(int argc, char *agrv) {
SliceDataIO *slice = readSliceData("W11.slice"); // 讀入切片資料
writeSliceData("W11copy.slice", slice); // 寫入切片資料
delete slice; // 釋放分配給類物件slice的動態記憶體空間
return 1;
}
執行主函式之後,程式將讀入W11.slice
,並將切片資料寫至W11copy.slice
中。
delete
:用以釋放動態分配的記憶體空間,要求被釋放的指標必須是指向動態分配的記憶體空間。
附錄
void*
void
被翻譯為“無型別”,相應的void*
為“無型別指標”。
- 當函式不需要返回值時,必須使用
void
限定,如:void func(int a,char *b)
; - 當函式不允許接受引數時,同樣必須使用
void
加以限定,如:int func(void)
。
void指標的使用規則:
1.void
指標可以指向任意型別的資料,即可以用任意型別的指標對void
指標賦值。如:
int *a;
void *p;
p = a; // int * 型的a可以直接賦值給void * 型的p
2.如果要將void
指標p
賦值給其他型別的指標,則需要強制型別轉換,如:a = (int *)p
。
在上文中提及的alloc2()
函式,其定義為:
void **alloc2(size_t n1, size_t n2, size_t size)
{
size_t i2;
void **p;
...
return p; // p是一個void ** 型的指標變數
}
而alloc2int()
函式的定義為:
int **alloc2int(size_t n1, size_t n2)
{
return (int**)alloc2(n1, n2, sizeof(int)); // 使用(int **)強制型別轉換
}
同理,可以依據此規則寫出alloc2bool()
:
bool **alloc2bool(size_t n1, size_t n2)
{
return (bool**)alloc2(n1, n2, sizeof(bool)); // 使用(bool **)強制型別轉換
}