2015-04-13 3 views
1

Я новичок в C++, и я пытаюсь преобразовать unordered_set<string> в vector<vector<int>>Преобразование набора в вектор вектора

Набор содержит ("1,2,2","1","1,2","2","2,2"), и каждый элемент является строкой. Я хотел бы вывести vector<vector<int>> содержащий

[ 
    [2], 
    [1], 
    [1,2,2], 
    [2,2], 
    [1,2], 
    [] 
] 

Так как я бы разобрать каждый элемент (строка) и сделать это выглядит как на приведенной выше схеме?

#define SSTR(x) dynamic_cast< std::ostringstream & >(\ 
     (std::ostringstream() << std::dec << x)).str() 

vector<vector<int> > subsetsWithDup(const vector<int> &num) { 
    unordered_set<string> result; 
    for (int i = 0; i < num.size(); i++) 
    { 
     result.insert(SSTR(num[i])); 
     for (int j = i+1; j < num.size(); j++) 
     { 
      string d = SSTR(num[i]) + "," +SSTR(num[j]); 
      result.insert(d); 
     } 
    } 

    string lastString= ""; 
    for (int i = 0; i < num.size(); i++) 
    { 
     if (i == num.size() -1) 
     { 
      lastString+= SSTR(num[i]); 
     } 
     else 
     { 
      lastString+= SSTR(num[i])+","; 
     } 
    } 

    result.insert(lastString); 

    // convert result back to vector<vector<int>> 
    return result; 
} 
+0

Я не могу сказать, в каком порядке вы хотите, чтобы они в - это, кажется, совершенно случайно! –

+0

заказ не важен – andre

+0

Итак, вы предоставили алгоритм: я не понимаю, что вы хотите от нас делать. Докажите, что это правильно? Возьмите его через отладчик и посмотрите, что это такое. – noobProgrammer

ответ

0

Если вам не нужно, чтобы проверить свои string S вы можете сделать transform для построения vector<vector<int>>:

set<string> foo{ "1,2,2", "1", "1,2", "2", "2,2" }; 
vector<vector<int>> bar(foo.size()); 

transform(foo.begin(), foo.end(), bar.begin(), [](const string& i){ 
    vector<int> result; 
    auto it = const_cast<char*>(i.c_str()); 

    for (result.push_back(static_cast<int>(strtol(it, &it, 10))); 
     it < i.c_str() + i.size(); 
     result.push_back(static_cast<int>(strtol(++it, &it, 10)))); 
    return result; 
}); 

лямбда в преобразовании шагнет через string: Start

  1. it в начале string
  2. Использование strtol для извлечения каждого номера
  3. Нажатие каждого номера в result
  4. Stepping над каждым ',' с ++it
  5. Возвращение Построенная result

Предпосылки: Это лямбда предполагает, что ваш вход set не содержит:

  • Пустой string
  • string, который начинается или заканчивается запятой (как в "1,2,")
  • string, который имеет последовательные запятые (как в "1,,2")
  • , что строка содержит только содержит цифры и запятые

Примечание: Как правило, const_cast плохо, поэтому я хотел бы прокомментировать, почему я его делаю. Обратите внимание, что *it никогда не записывается, только для it. Так что это не нарушает const -ness const string& i. Альтернативой strtol, которая не требуется const_cast, является stoi, но до тех пор, пока мы не получим string_view из C++ 14, нам нужно будет создать новый string в каждой запятой, так что это ужасно неэффективно.

0

Одним из возможных решений может быть:

vector<string> split (string str, string seq) { 
     vector<string> ret {}; 
     size_t pos {}; 

     while ((pos = str.find (seq)) != string::npos) { 
      ret.push_back (str.substr (0, pos)); 
      str = str.substr (pos+seq.size()); 
     } 
     ret.push_back (str); 

     return ret; 
} 

vector<int> to_vec_int (vector<string>&& vec) { 
     vector<int> ret {}; 

     for (const auto& v : vec) { 
       ret.push_back (stoi (v)); 
     } 
     return ret; 
} 

int main() { 
     unordered_set<string> st {"1,2,2","1","1,2","2","2,2"}; 
     vector<vector<int>> vec {}; 
     for (const auto& s : st) { 
       vec.push_back (to_vec_int (split (s, ","))); 
     } 

     for (const auto& v : vec) { 
       for (const auto& s : v) { 
         cout << s << " "; 
       } 
       cout << endl; 
     } 

     return 0; 
} 

Поскольку ваши элементы разделяются запятой, мы можем разделить их, используя функцию разделения() и мы получаем вектор строк. Этот вектор должен быть преобразован в вектор int, что является причиной существования to_vec_int().

0

Вот еще один из возможных решений с помощью istringstream найти запятые:

#include <iostream> 
#include <string> 
#include <vector> 
#include <unordered_set> 
#include <sstream> 

void main() 
{ 
    using namespace std; 
    unordered_set<string> strSet; 
    strSet.insert("1,2,2"); 
    strSet.insert("1"); 
    strSet.insert("1,2"); 
    strSet.insert("2"); 
    strSet.insert("2,2"); 
    vector<int> nums; 
    vector<vector<int>> arr_of_nums; 

    for (const auto &str : strSet) { 
     istringstream strStream(str); 
     string strToInt; 
     while (getline(strStream, strToInt, ',')) { 
      nums.push_back(stoi(strToInt)); 
     } 
     arr_of_nums.push_back(nums); 
     nums.clear(); 
    } 
    for(const auto &nums : arr_of_nums) { 
     for (const auto &num : nums) { 
      cout << num << ","; 
     } 
     cout << endl; 
    } 
} 
Смежные вопросы