Как скомбинировать вектора в С++

Рейтинг: -1Ответов: 3Опубликовано: 09.05.2023
#include <string>
#include <vector>
#include <iostream>

есть вектора:

std::vector<int> one = {1, 2, 4};
  std::vector<int> two = {1, 2, 3, 5};
  std::vector<int> three = {2, 3, 6};
  std::vector<int> four = {4, 4, 5, 7};
  std::vector<int> five = {2, 4, 5, 6, 8};
  std::vector<int> six = {3, 5, 6, 9};
  std::vector<int> seven = {4, 7, 8};
  std::vector<int> eight = {0, 5, 7, 8, 9};
  std::vector<int> nine = {6, 8, 9};
  std::vector<int> zero = {0, 8};

так же к этим векторам есть ключ

std::map<int, std::vector<int>> rule = {
      {0, zero},
      {1, one},
      {2, two},
      {3, three},
      {4, four},
      {5, five},
      {6, six},
      {7, seven},
      {8, eight},
      {9, nine}
  };

даётся ввод: 15 и нам нужно скомбинировать вектора one и five,

чтобы на выходи получили: 12, 14, 15, 16, 18, 22, 24, 25, 26, 28, 42, 44, 45, 46, 48

если ввод: 3

то на выходе мы получаем: 2, 3, 6

как реализовать комбинацию векторов ? Если ввод может быть любым целым числом ( 1, 56 или 46327)

Ответы

▲ 2Принят

Можно обойтись без чисел. Рекурсия, работа с текстами:

#include <iostream>
#include <string>

const std::string rule[] = {
    "08"   , "124" , "1235", "236"  , "4457",
    "24568", "3569", "478" , "05789", "689"
};

void combine(const std::string &prefix, const std::string &key) {
    if (key.empty()) {
        std::cout << prefix;
    } else {
        for (auto c : rule[key[0] - '0']) {
            combine(prefix + c, key.substr(1));
        }
    }
}

int main() {
    std::string key;
    std::cin >> key;
    combine(" ", key);
    std::cout << '\n';
}
$ g++ -std=c++17 -pedantic -Wall -Wextra -Werror -Wwrite-strings -Wconversion combine.cpp 

$ echo 15 | ./a.out
 12 14 15 16 18 22 24 25 26 28 42 44 45 46 48

$ echo 3 | ./a.out
 2 3 6

$ echo 1 | ./a.out
 1 2 4

$ echo 56 | ./a.out
 23 25 26 29 43 45 46 49 53 55 56 59 63 65 66 69 83 85 86 89

$ echo 46327 | ./a.out
 43214 43217 43218 43224 43227 ... 79637 79638 79654 79657 79658
▲ 4

Годится?

vector<int> make(int n)
{
    vector<int> r;
    if (n < 0 || n >= 100) return r;  // Ну на всякий пожарный...
    for(auto a: rule[n/10])
        for(auto b: rule[n%10])
            r.push_back(a*10+b);
    return r;
}

int main(int argc, char * argv[])
{
    for(auto x: make(15)) cout << x << "  ";
}

Для любой (разумной :), проверки в этот раз я не делаю, оставляю в качестве самостоятельной работы) длины

vector<int> make(int n)
{
    if (n < 10) return rule[n];

    vector<int> f = make(n/10);
    vector<int> res;
    for(auto x: f) for(auto y: rule[n%10]) res.push_back(x*10+y);
    return res;
}
▲ 0
#include <string>
#include <vector>
#include <iostream>
#include <map>

std::vector<std::string> get_pins(std::string observed) {
  // правило
  std::vector<int> one = {1, 2, 4};
  std::vector<int> two = {1, 2, 3, 5};
  std::vector<int> three = {2, 3, 6};
  std::vector<int> four = {1, 4, 5, 7};
  std::vector<int> five = {2, 4, 5, 6, 8};
  std::vector<int> six = {3, 5, 6, 9};
  std::vector<int> seven = {4, 7, 8};
  std::vector<int> eight = {0, 5, 7, 8, 9};
  std::vector<int> nine = {6, 8, 9};
  std::vector<int> zero = {0, 8};
  std::map<int, std::vector<int>> rule = {
      {0, zero},
      {1, one},
      {2, two},
      {3, three},
      {4, four},
      {5, five},
      {6, six},
      {7, seven},
      {8, eight},
      {9, nine}
  };
  
  std::vector<unsigned int> nums; // это вектор observed. если observed = "123" то nums = {1, 2, 3}
  std::vector<std::string> result;
  std::string sums;
  std::vector<int> mixed;
  
  // преобразует  строку в число и помещает его в вектор
  for (char c : observed)
  {
        int digit = c - '0'; 
        nums.push_back(digit);
  }
  
  if (nums.size() == 1)
  {
        std::vector<int> options = rule[nums[0]];
        // по очереди i принимает значения options и записывает каждое значение в текстовый вектор result
        for (int i : options)
        {
            result.push_back(std::to_string(i));
        }
        return result;
  }

  if(nums.size() > 1)
  {
      // определяет функцию recursive_fun, которая рекурсивно находит все возможные комбинации пин-кодов.
      std::function<void(int)> recursive_fun = [&](int pos)
      {
          //прошлись ли мы по всем возможным комбинациям
          if(pos == nums.size())
          {
              result.push_back(sums);
              return;
          }   
          for(auto num : rule[nums[pos]])
          {   
              //добавляем текущее число
              sums.push_back(num + '0');
              recursive_fun(pos + 1);
              sums.pop_back();
          }
      };
      recursive_fun(0);
  }
  
  return result; 
}

где проверки являются

It(Tests)
    {
        std::vector<std::string> output = get_pins("8"); std::sort(output.begin(), output.end());
        std::vector<std::string> result = {"0", "5", "7", "8", "9"};
        Assert::That(output, Equals(result));
        
        output = get_pins("11"); std::sort(output.begin(), output.end());
        result = {"11", "12", "14", "21", "22", "24", "41", "42", "44"};
        Assert::That(output, Equals(result));
        
        output = get_pins("369"); std::sort(output.begin(), output.end());
        result = {"236", "238", "239", "256", "258", "259", "266", "268", "269", "296", "298", "299", "336", "338", "339", "356", "358", "359", "366", "368", "369", "396", "398", "399", "636", "638", "639", "656", "658", "659", "666", "668", "669", "696", "698", "699"};
        Assert::That(output, Equals(result));
    }