Doxygenもっと日本語対応 作品解説  2013-11-25
 全て クラス ファイル 関数 変数 列挙型 列挙値 ページ
順列.cpp
[詳解]
1 #include <algorithm>
2 #include <iostream>
3 #include "順列.h"
4 
22 unsigned int 階乗( const unsigned int 値, const unsigned int 開始値 = 1 )
23 {
24  if ( 値 <= 開始値 ) { return 1; }
25  return 値 * 階乗( 値 - 1, 開始値 );
26 }
27 
28 
39 template<class T> void 全表示本体( T* ptr )
40 {
41  ptr->初期化();
42  int cnt = 1;
43  for ( std::vector<unsigned int> seq = ptr->次(); seq.size(); seq = ptr->次() )
44  {
45  std::wcout << cnt++ << L":";
46  for ( auto it = seq.rbegin(); it != seq.rend(); ++it )
47  {
48  std::wcout << wchar_t( L'a' + *it );
49  }
50  std::wcout << std::endl;
51  }
52  std::wcout << L"あるべき長さ = " << ptr->総数() << std::endl;
53 }
54 
55 
61 順列::順列( const unsigned int 元数, const unsigned int 取得長さ )
62  : m元数( 元数 ), m取得長さ( 取得長さ ? 取得長さ : 元数 )
63 {
64 }
65 
66 
75 std::vector<unsigned int> 順列::次()
76 {
77  // 各桁の値が重複しない昇順という感じの単純な実装です。
78  // ここでは添え字の小さいほうが下位桁相当。
79  if ( m現況.size() == 0 )
80  {
81  for ( unsigned int i = 0; i < m取得長さ; ++i )
82  {
83  m現況.push_back( m取得長さ - 1 - i );
84  }
85  return m現況;
86  }
87  std::vector<unsigned int> sub( m現況 );
88  auto subIt = sub.begin();
89  for ( unsigned int 桁 = 0; 桁 < m取得長さ; ++桁 )
90  {
91  ++subIt;
92  for ( unsigned int 値 = m現況[ 桁 ] + 1; 値 < m元数; ++値 )
93  {
94  if ( std::find( subIt, sub.end(), 値 ) != sub.end() )
95  {
96  continue;
97  }
98  m現況[ 桁 ] = 値;
99  unsigned int c = 0;
100  for ( unsigned int k = 桁; k > 0; --k )
101  {
102  for ( ; ; ++c )
103  {
104  if ( c != 値 && std::find( subIt, sub.end(), c ) == sub.end() )
105  {
106  m現況[ k - 1 ] = c++;
107  break;
108  }
109  }
110  }
111  return m現況;
112  }
113  }
114  m現況.clear();
115  return m現況;
116 }
117 
118 
124 unsigned int 順列::総数() const
125 {
126  return 階乗( m元数, m元数 - m取得長さ );
127 }
128 
129 
137 {
138  全表示本体( this );
139 }
140 
141 
147 組み合わせ::組み合わせ( const unsigned int 元数, const unsigned int 取得長さ )
148  : m順列( 元数, 取得長さ )
149 {
150 }
151 
152 
161 std::vector<unsigned int> 組み合わせ::次()
162 {
163  // 順列の中から各桁の値が昇順になっているものだけ返しています。
164  std::vector<unsigned int> r( m順列.() );
165  for ( ; r.size(); r = m順列.() )
166  {
167  auto it = r.begin();
168  unsigned int prev = *it;
169  for ( ++it; it != r.end(); ++it )
170  {
171  if ( prev <= *it ) { break; }
172  prev = *it;
173  }
174  if ( it == r.end() ) { break; }
175  }
176  return r;
177 }
178 
179 
184 unsigned int 組み合わせ::総数() const
185 {
187 }
188 
189 
196 {
197  全表示本体( this );
198 }
std::vector< unsigned int > 次()
次の配列を生成して返します
Definition: 順列.cpp:161
unsigned int m元数
要素の種類数です
Definition: 順列.h:49
unsigned int m取得長さ
毎回返す集合の大きさです
Definition: 順列.h:50
void 全表示本体(T *ptr)
順列や組み合わせの一巡内容を表示します、デバッグ用です
Definition: 順列.cpp:39
void 全表示()
すべての解答を構築し、標準出力に流します、デバッグ用です
Definition: 順列.cpp:136
std::vector< unsigned int > 次()
次の配列を生成して返します
Definition: 順列.cpp:75
順列(const unsigned int 元数, const unsigned int 取得長さ=0)
構築子
Definition: 順列.cpp:61
順列 m順列
出力する組み合わせの元になる順列
Definition: 順列.h:94
std::vector< unsigned int > m現況
直前に返した組を保持しています
Definition: 順列.h:52
void 全表示()
すべての解答を構築し、標準出力に流します、デバッグ用です
Definition: 順列.cpp:195
順列または組み合わせの反復取得クラスを宣言しているヘッダファイルです
unsigned int 総数() const
構築子で与えられた設定において幾通りの解答があるかを返します
Definition: 順列.cpp:124
unsigned int 階乗(const unsigned int 値, const unsigned int 開始値=1)
階乗もしくは階乗の部分積を返します
Definition: 順列.cpp:22
組み合わせ(const unsigned int 元数, const unsigned int 取得長さ=0)
構築子
Definition: 順列.cpp:147
unsigned int 総数() const
構築子で与えられた設定において幾通りの解答があるかを返します
Definition: 順列.cpp:184