SigUtil  0.95
Utility modules for modern C++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
others.hpp
Go to the documentation of this file.
1 #ifndef SIG_UTIL_SET_HPP
2 #define SIG_UTIL_SET_HPP
3 
4 #include "sigutil.hpp"
5 #include "tool.hpp"
6 
7 namespace sig
8 {
9 
10 #if SIG_ENABLE_BOOST
11 
12  //条件に最適な値とそのIndexを探す. comp(比較対象値, 暫定最小値)
13  template < class T, class CMP, template < class T, class = std::allocator<T>> class Container >
14  maybe<std::tuple<T, uint>> SearchIndex(Container<T> const& src, CMP comp)
15  {
16  if (src.empty()) return nothing;
17 
18  T val = src[0];
19  uint index = 0;
20 
21  for (uint i = 0, size = src.size(); i < size; ++i){
22  if (comp(src[i], val)){
23  val = src[i];
24  index = i;
25  }
26  }
27 
28  return std::make_tuple(val, index);
29  }
30 
31 #endif
32 
33 
34  inline void Print(std::string const& text, char const* const delimiter = "\n")
35  {
36  std::cout << text << delimiter;
37  }
38 
39  inline void Print(std::wstring const& text, wchar_t const* const delimiter = L"\n")
40  {
41  std::wcout << text << delimiter;
42  }
43 
44  template < class T, template <class...> class Container, typename std::enable_if<!std::is_same<T, std::wstring>::value>::type*& = enabler>
45  inline void Print(Container<T> const& container, char const* const delimiter = "\n")
46  {
47  std::copy(container.begin(), container.end(), std::ostream_iterator<T>(std::cout, delimiter));
48  }
49 
50  template<template<class...> class Container>
51  inline void Print(Container<std::wstring> const& container, wchar_t const* const delimiter = L"\n")
52  {
53  std::copy(container.begin(), container.end(), std::ostream_iterator<std::wstring>(std::wcout, delimiter));
54  }
55 
56 
57 template <class CC1, class CC2>
58 auto GaleShapley(CC1 const& men_vec, CC2 const& women_vec)
59 {
60  assert(men_vec.size() != women_vec.size());
61 
62  uint total = men_vec.size();
63  std::vector<uint> keeping(total, total+1); // 女性が 何位の男性と婚約しているか(初期値N+1)
64  std::vector<std::tuple<bool, uint>> single_men(total, std::make_tuple(true, 0)); // 男性が tuple<独身であるか, 告白回数(希望相手女性の順位)>
65  std::queue<uint> rest; // 告発実行待ちの男性のキュー
66 
67  // 男性が女性に告白する。戻り値:婚約成功の可否
68  auto propose = [&](const uint man, const uint woman) ->bool{
69  if(keeping[woman] > total){
70  // womanがまだ婚約していない場合
71  keeping[woman] = man;
72  std::get<0>(single_men[man]) = true;
73  return true;
74  }
75  else{
76  for(uint i=0; i<total; ++i){
77  if(man == women_vec[woman][i]){
78  if(i < keeping[woman]){
79  // manがwomanの婚約相手よりも好感度が高い場合
80  uint now_man = women_vec[woman][keeping[woman]];
81  keeping[woman] = i;
82  std::get<0>(single_men[man]) = true;
83  // 現婚約者の婚約解消
84  std::get<0>(single_men[now_man]) = false;
85  rest.push(now_man);
86  return true;
87  }
88  else{
89  return false;
90  }
91  }
92  }
93  }
94  };
95 
96  for(uint i=0; i<total; ++i) rest.push(i);
97 
98  while (!rest.empty()){
99  const uint man = rest.front();
100  const uint propose_woman = men_vec[man][std::get<1>(single_men[man])];
101  ++std::get<1>(single_men[man]);
102  if (propose(man, propose_woman)) rest.pop();
103  }
104 }
105 }
106 
107 #endif
void Print(std::string const &text, char const *const delimiter="\n")
Definition: others.hpp:34
void * enabler
auto GaleShapley(CC1 const &men_vec, CC2 const &women_vec)
Definition: others.hpp:58
Definition: array.hpp:15
auto copy(C &&src) -> RC
別の種類のコンテナに要素をコピーする