C++中用Vector容器存儲矩陣

主要記錄兩點:
1、用vector定義可變長度數組
2、用vector按多字段值排序(數組中存儲具有多個屬性的類,按照類的某一屬性進行排序)
3、從文件讀入鄰接矩陣,用vector存儲矩陣進而求節點度的實例

1、用vector定義數組

在設計程序常會碰到這樣的問題,需要根據輸入數據來確定所用數組的大小,或者數組長度需要隨程序運行動態變化。
這時有兩種思路來設計可變長度的數組:
一種是用new 和 delete來動態分配和釋放內存,從而達到動態數組的目的。

int len; 
cin>>len;
int *p=new int[len]; 
......
delete[] p;

上面代碼根據輸入參數len來定義一個長度爲len的數組,這裏如果直接寫

int len;
cin>>len;
int p[len];

是有問題的,因爲這種形式的數組長度是在編譯的時候確定的,故而後面的參數必須是一個常數。
還有要注意的是int *p=new int[len]開闢的內存必須用delete[] p來釋放。
另一種是用C++標準模版庫(STL)中的vector實現變長數組。

int len;
cin>>len;
vector<int> array(len);

後面要使用數組array的時候跟普通數組一樣用array[i]就可以了。
這一部分主要參考C++動態數組
下面是用vector定義確定大小的二維數組

vector<vector<double>> A(5,vector<double>(5));//定義一個5*5的二維數組

下面是一個根據輸入來確定數組大小的例子:
面試的時候在線編程要求第一行輸入數據組數N,第二行輸入行數R和列數C
接下來輸入N組R*C的二維數組

/**********************************************************
*                    test.cpp
*
* 第一行輸入數據組數N,第二行輸入行數R和列數C,接下來輸入N組R*C的二維數組
*
* 張京林, 2016-3
*********************************************************/
#include <iostream>
#include <vector>
using namespace std;

void main() 
{
    int N, R, C, num;   
    cin >> N;//N組測試數據
    vector<vector<vector<int>>> testarray(N);
    //vector<vector<vector<int>>> testarray;//配合push_back使用
    cin >> R >> C;//每組數據都是R行C列的二維數組
    vector<vector<int>> array(R,vector<int>(C));
    for (int n = 0; n < N; n++)
    {
        for (int i = 0; i < R; i++)
        {
            for (int j = 0; j < C; j++)
            {
                cin >> num;
                array[i][j] = num;
            }
        }
        //testarray.push_back(array);
        testarray[n] = array;//可以直接賦值
    }
    getchar();//停留在結果界面
}

2、用vector按多字段值排序

有時候我們想把類對象存在數組裏,後續操作希望能夠根據對象不同的屬性來對數組重新排序,這時候我們就需要用到sort函數了。

class Student
{
private:
    int id;             // 學號
    float eyesight;     // 視力
    float height;       // 身高
public:
Student(int id, float eyesight, float height)
    {
        this->id = id;
        this->eyesight = eyesight;
        this->height = height;
    }
int get_id()
    {
        return id;
    }

    float get_eyesight()
    {
        return eyesight;
    }

    float get_height()
    {
        return height;
    }
    // 比較大小的函數(謂詞)
bool comparer(Student& stu_a, Student& stu_b)
{
    // 按eyesight升序 + height升序排列
    if(stu_a.get_eyesight() != stu_b.get_eyesight())    
        return (stu_a.get_eyesight() < stu_b.get_eyesight());
    else
        return (stu_a.get_height() < stu_b.get_height());
}
int main(int argc, char** argv)
{
    vector<Student> vec;
    vec.push_back(Student(4, 1.1f, 170.2f));
    vec.push_back(Student(3, 1.1f, 163.4f));
    vec.push_back(Student(2, 1.5f, 166.6f));
    vec.push_back(Student(1, 1.5f, 173.2f));

    // 調用STL中的sort函數,其中的第三個參數就是我們前面定義的,比較兩個Student對象大小的函數
    sort(vec.begin(), vec.end(), comparer);

    vector<Student>::iterator iter;
    for(iter = vec.begin(); iter != vec.end(); ++iter)
    {
        cout << (*iter).get_eyesight() << "\t" << (*iter).get_height() << endl;
    }
    return 0;
}

這裏主要參考STL vector按多字段值排序

3、用vector存儲矩陣求節點度的實例

下面是我寫的一個應用,通過文件讀入一個鄰接矩陣,然後根據鄰接矩陣計算各節點的度,並按照節點的度排序,以研究度中心性(degree  centrality )。我定義了一個node類,有兩個屬性:index和degree,我根據degree排序之後可以通過查詢index知道該位置的是哪個節點。

/**********************************************************
*                    centrality.cpp
*
* 無向圖的中心性
*
* 根據無向圖節點的度中心性來尋找中心節點
*
* 張京林, 2015-4
*********************************************************/
#include "centrality.h"
#include "node.h"

using namespace std;

int main(void)
{
    adj_Mat G = input();
    int N = G.size();
    vector<int> degree(N);  //數組用於暫時存儲計算得到的節點的度
    vector<node> Nodes(N);  //矩陣的節點

    for (unsigned int i = 0; i < G.size(); i++)
    {
        degree[i] = 0;
    }
    //打印讀入的鄰接矩陣
    /*for (unsigned int i = 0; i < G.size(); i++)
    {
        for (unsigned int j = 0; j < G[i].size(); j++)
        {
            cout << G[i][j] << "" << flush;
        }
        cout << endl;
    }*/

    //根據鄰接矩陣計算各節點的度
    for (unsigned int i = 0; i < G.size(); i++)
    {
        for (unsigned int j = 0; j < G[i].size(); j++)
        {
            if (G[i][j] == 1 && i!=j)
                degree[i]++;
        }   
        Nodes[i].set_index(i);
        Nodes[i].set_degree(degree[i]);
    }
    //根據compare_degree規定的規則對數組內的節點排序
    sort(Nodes.begin(), Nodes.end(), compare_degree);

    return 0;       
}
/*********************************************************
*                        node.h
*
* 定義了一個節點類
*
* 張京林, 2015-4
**********************************************************/
#pragma once
#include <vector>

class node
{
public:
    node();
    ~node();
    //設置與獲取節點序號
    int set_index(int i);
    int get_index();
    //設置與獲取節點的度
    int set_degree(int i);
    int get_degree();

private:
    int index;//節點序號
    int degree;//節點的度
};

node::node()
{
    index = 0;
    degree = 0;
}

node::~node()
{
}

int node::set_index(int i)
{
    index = i;
    return 0;
}

int node::get_index()
{
    return index;
}

int node::set_degree(int i)
{
    degree = i;
    return 0;
}

int node::get_degree()
{
    return degree;
}
/*********************************************************
*                    centrality.h
*
* centrality.cpp的頭文件
*
* 定義了文件讀取函數adj_Mat input();和排序規則函數bool compare_degree(node& node_a, node& node_b);
*
* 張京林, 2015-4
**********************************************************/
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>    //sort必須包含這個頭文件
#include <sstream>      //istringstream 必須包含這個頭文件
#include "node.h"

using namespace std;

bool compare_degree(node& node_a, node& node_b);//用於sort的第三個參數,設定排序規則
typedef vector<vector<int>> adj_Mat; //鄰接矩陣
adj_Mat input();

//按照節點度降序排列
bool compare_degree(node& node_a, node& node_b)
{
    return (node_a.get_degree() > node_b.get_degree());
}

adj_Mat input()
{
    ifstream infile("graph1.txt");//從文件讀入鄰接矩陣
    adj_Mat matrix;
    istringstream istr;
    string str;
    vector<int> tmpvector;
    while (getline(infile, str))
    {
        istr.str(str);
        int tmp;
        while (istr >> tmp)
        {
            tmpvector.push_back(tmp);//先讀入一行數據,存在一個一個向量(數組)中
        }
        matrix.push_back(tmpvector);//再把每個行向量作爲一個元素存到另一個向量(數組)中
        tmpvector.clear();
        istr.clear();
    }
    infile.close();
    return matrix;
}
發佈了40 篇原創文章 · 獲贊 153 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章