2013-03-21 4 views
0

У меня есть карта, определяемая как map<string, vector<double> >.Печать карты STL в виде таблицы

Как распечатать это как таблицу. Я хочу, чтобы ключ карты в качестве заголовка строки таблицы и каждый столбец таблицы будет vector

Say моя первая карта была

hash = { 
    "a": [1, 2, 3], 
    "b": [1, 2, 3] 
} 

Я хочу, чтобы это напечатано как

a b 
1 1 
2 2 
3 3 
+1

вам это нужно, чтобы быть оправданным, или вы только требуют пробельных, ограничивающей ли? – Wug

+0

whitesapce delimiting ... в основном я хочу записать его в файл csv – subzero

+0

Все ли векторы гарантированно имеют одинаковый размер? – metal

ответ

2

Вот возможная реализация с использованием C++ 11 (здесь я ожидаю все векторы имеют тот же размер):

#include <map> 
#include <string> 
#include <vector> 
#include <iostream> 

void print(std::map<std::string, std::vector<double>> const& m) 
{ 
    // Do nothing for an empty table... 
    if (m.begin() == m.end()) { return; } 

    for (size_t i = 0; i <= m.begin()->second.size(); i++) 
    { 
     for (auto const& p : m) 
     { 
      if (i == 0) { std::cout << p.first << " "; } 
      else { std::cout << p.second[i - 1] << " "; } 
     } 

     std::cout << std::endl; 
    } 
} 

int main() 
{ 
    std::map<std::string, std::vector<double>> m = { 
     { "a", { 1, 2, 3, 0 } }, 
     { "b", { 2, 4, 6, 1 } }, 
     { "c", { 9, 2, 3, 2 } } 
    }; 

    print(m); 
} 

И вот live example.

+0

+1 для C++ 11 более кратким и изящным – gongzhitaao

+0

это просто печать первых трех значений векторного поля – subzero

+0

@subzero: Это изначально было, но я обновил свой ответ (см. Связанный живой пример) –

0
#include <iostream> 
#include <map> 
#include <string> 
#include <vector> 
using namespace std; 

int main() 
{ 
    map<string, vector<double> > m; 
    vector<double> a, b, c; 
    for (int i = 0; i < 4; ++i) a.push_back(i); 
    for (int i = 0; i < 6; ++i) b.push_back(i); 
    for (int i = 0; i < 7; ++i) c.push_back(i); 
    m["a"] = a; 
    m["b"] = b; 
    m["c"] = c; 

    int n = max(max(a.size(), b.size()), c.size()); 
    for (map<string, vector<double> >::iterator i = m.begin(); i != m.end(); ++i) 
     cout << i->first << ','; 
    cout << endl; 

    for (int i = 0; i < n; ++i) { 
     for (map<string, vector<double> >::iterator it = m.begin(); it != m.end(); ++it) 
      cout << (i < it->second.size() ? it->second[i] : 0) << ','; 
     cout << endl; 
    } 
} 

Я считаю, что есть более эффективные способы сделать итерацию и иметь дело с задней ,.

3

Flexible для произвольных столбцов и длины варианта

void print(const map<string, vector<double>> &m) 
{ 
    size_t rows = 0; 
    for (auto const &i : m) 
    { 
     cout << i.first << ' '; 
     if (i.second.size() > rows) 
      rows = i.second.size(); 
    } 
    cout << endl; 
    for (size_t r = 0; r < rows; ++r) 
    { 
     for (auto const &i : m) 
      if (r < i.second.size()) 
       cout << i.second[r] << " "; 
      else 
       cout << " "; 
     cout << endl; 
    } 
} 
int main() 
{ 
    map<string, vector<double> > m = { 
     { "a", { 1, 2, 3}}, 
     { "b", { 1, 2, 3, 4}}, 
     { "c", { 1, 2}}, 
     { "d", { 1}}, 
     { "e", { 1, 2, 3, 4, 5, 6, 7}} 
    }; 
    print(m); 
} 

Выходной

a b c d e 
1 1 1 1 1 
2 2 2 2 
3 3  3 
    4  4 
     5 
     6 
     7 

Live исходный код.

0

Это решение будет работать для произвольного количества столбцов, каждое из которых имеет произвольное количество строк.

И названия колонок также произвольной длины.

#include <map> 
#include <string> 
#include <vector> 
#include <iostream> 

void print(std::map<std::string, std::vector<double>> const& m) 
{ 
    std::vector<size_t> columnWidths; 
    std::vector< std::vector<std::string>> columns; 
    size_t totalRows = 0; 

    // Store all table elements, and the required width of each column 
    for (auto a : m) 
    { 
     std::vector<std::string> column; 
     size_t width = a.first.length(); 
     column.push_back(a.first); 
     size_t rows = 1; 

     for (auto v : a.second) 
     { 
      ++rows; 
      std::string entry = std::to_string(v); 
      width = std::max(width, entry.length()); 
      column.push_back(entry); 
     } 
     columnWidths.push_back(width); 
     columns.push_back(column); 
     totalRows = std::max(totalRows, rows); 
    } 

    // Print all table elements 
    for (size_t row = 0; row != totalRows; ++row) 
    { 
     for (size_t col = 0; col != columns.size(); ++col) 
     { 
      std::string entry; 
      if (columns[col].size() > row) 
      { 
       entry = columns[col][row]; 
      } 
      entry.resize(columnWidths[col], ' '); 
      std::cout << entry << ' '; 
     } 
     std::cout << '\n'; 
    } 
} 

int main() 
{ 
    std::map<std::string, std::vector<double>> m = 
    { 
     { "a", { 1, 2, 3} }, 
     { "a really really long string", { 1, 2, 3} }, 
     { "b", { 1, 2, 3, 4, 5 } } 
    }; 

    print(m); 
} 
1

Это работает с векторами различной длины:

#include <iostream> 
#include <map> 
#include <vector> 
#include <string> 

using namespace std; 

int main() 
{ 

    map<string,vector<double> > hashes; 
    double arr[]={1,2,3}; 
    double arr2[]={1,2,3,4}; 
    hashes.insert(pair<string,vector<double> >("a",vector<double>(arr,arr+sizeof(arr)/sizeof(double)))); 
    hashes.insert(pair<string,vector<double> >("b",vector<double>(arr,arr+sizeof(arr)/sizeof(double)))); 
    hashes.insert(pair<string,vector<double> >("c",vector<double>(arr2,arr2+sizeof(arr2)/sizeof(double)))); 

    for(auto i: hashes) 
    { 
     cout<< i.first << ' '; 
    } 
    cout << endl; 
    int max_len=0; 
    for(auto i: hashes) 
    { 
    if(i.second.size()>max_len) max_len=i.second.size(); 
    } 
    for(int h=0; h<max_len; h++) 
    { 

    for(auto i: hashes) 
    { 
     if(h>=i.second.size()) cout << " "; 
     else cout << i.second[h] << " "; 
    } 
    cout << endl; 
} 
return 0; 
} 

Выход:

a b c 
1 1 1 
2 2 2 
3 3 3 
    4 
Смежные вопросы