Top/article/Loop-over-N-int-variables
English | Japanese
English | Japanese

Menu

  • Top
  • Akihiko Yamaguchi 山口 明彦
  • Project プロジェクト
  • Text テキスト
  • Recent articles 最近の記事
  • Articles 記事一覧 (a to z)
  • Search 検索

Tags タグ †

  • [c++][bash][python][latex][php]
  • [linux][windows][mac][android]
  • [math][algorithm][idea][trick]
  • [liboctave][opencv][git][ros]
  • [setting][bug][general]
↑

Recent articles 最近の記事 †

2019-07-02
  • article/Display-Unix-Time
  • article/Synchronize-Linux-Time-to-Remote
2018-09-27
  • article/python-multimode-singleton
2018-09-02
  • article/rosinstall-git-default-remote
2017-07-28
  • article/SubMenu
2017-03-05
  • article/Import-a-different-version-of-OpenCV-in-Python
2015-08-17
  • article/DRC-finals-2015
2015-01-05
  • article/Upgrade-Android-to-Lollipop
2015-01-01
  • article/Kernel-panic-of-Linux-when-using-Xtion
  • article/Do-not-skip-freeing-data-when-using-tri-mesh-in-ODE
Access: 1/2178 - Admin
These search terms have been highlighted:[algorithm]

Class to generate a loop over N integer variables

N整数変数のループ生成クラス

[c++][algorithm]
2008-07-06

x, y をそれぞれ (0,49), (0,20) の範囲で繰り返したい場合は,2重に for ループを書けばよい.変数が x, y, z なら3重にforループを書く.NならN重ループ.このNが何らかの事情でコンパイル以前に決められない場合はどうしよう. 解決策はいくらでもあると思うが,すべての組合せを生成するクラスを書いてみた.

class TAllPair
{
public:
  typedef std::size_t               value_type;
  typedef value_type&               reference;
  typedef const value_type&         const_reference;
  typedef std::vector<value_type>   set_type;
  typedef set_type::iterator        iterator;
  typedef set_type::const_iterator  const_iterator;
  typedef set_type::reverse_iterator        reverse_iterator;
  typedef set_type::const_reverse_iterator  const_reverse_iterator;
private:
  set_type  d, size;
  bool      include_zero_size;
public:
  template <typename InputIterator>
  TAllPair (InputIterator sizefirst, InputIterator sizelast)
      : include_zero_size(false)
    {
      for(InputIterator i(sizefirst); i!=sizelast; ++i)
      {
        size.push_back(*i);
        if (*i<=0)  include_zero_size=true;
      }
      d.resize (size.size(), 0);
    };
  iterator                begin(void)       {return d.begin();};
  const_iterator          begin(void) const {return d.begin();};
  reverse_iterator        rbegin(void)       {return d.rbegin();};
  const_reverse_iterator  rbegin(void) const {return d.rbegin();};
  iterator                end(void)       {return d.end();};
  const_iterator          end(void) const {return d.end();};
  reverse_iterator        rend(void)       {return d.rend();};
  const_reverse_iterator  rend(void) const {return d.rend();};
  reference               operator[] (int i)       {return d[i];};
  const_reference         operator[] (int i) const {return d[i];};

  void init (void)
    {for(iterator itr(begin()); itr!=end(); ++itr) *itr=0;};
  bool cont (void) const
    {
      if (include_zero_size)  return false;
      if (d.back()>=size.back())
        return false;
      else return true;
    };
  bool step (void)
    {
      const_iterator sizeitr (size.begin());
      for(iterator itr(begin()); itr!=end(); ++sizeitr,++itr)
      {
        if (*itr+1<*sizeitr) {++(*itr); break;}
        if (itr==end()-1) {*itr=*sizeitr;}
        else *itr=0;
      }
      return cont();
    };
};

クラス名 TAllPair がすこぶる適当なのは置いておいて,

  const int A[] = {2,3,3};
  TAllPair a(A,A+sizeof(A)/sizeof(int));
  a.init();
  for (a.init(); a.cont(); a.step())
    std::cout << a[0] << " : " << a[1] << " : " << a[2] << std::endl;

こんな感じで使えば,

 0 : 0 : 0
 1 : 0 : 0
 0 : 1 : 0
 1 : 1 : 0
 0 : 2 : 0
 1 : 2 : 0
 0 : 0 : 1
 1 : 0 : 1
 0 : 1 : 1
 1 : 1 : 1
 0 : 2 : 1
 1 : 2 : 1
 0 : 0 : 2
 1 : 0 : 2
 0 : 1 : 2
 1 : 1 : 2
 0 : 2 : 2
 1 : 2 : 2

みたいな結果が得られる.Aはstd::vectorでもok.

a[0]とかのアクセスがダサいとお考えなら,

  const int A[] = {2,3,3};
  for (TAllPair a(A,A+sizeof(A)/sizeof(int)); a.cont(); a.step())
  {
    for (TAllPair::const_iterator itr(a.begin()); itr!=a.end(); ++itr)
      std::cout << " " << *itr;
    std::cout << std::endl;
  }

のようにしてもほぼ同じ結果になる.




Last-modified:2014-12-30 (Tue) 18:35:03 (3841d)
Site admin: Akihiko Yamaguchi.
Written by: Akihiko Yamaguchi.
System: PukiWiki 1.5.0. PHP 5.2.17. HTML conversion time: 0.008 sec.