C++の最近のブログ記事

キッカケ> ソートアルゴったーturuginaは『イントロソート』です。 と言われて、イントロソートってなんやねん って Wikipediaで調べてた
ら、ネタソートの内、ストゥージソート ってのが日本語版にはなくて、気になったので、さらに色々探し回って 英語版Wikipedia に Stooge sort の項を見つけて、割と簡単そうなんでじゃぁ実装してみるか。って実装してみた。 とかそんな感じ

という、問題が 去年の12月に 既にQtのバグトラッカに登録されている QTCREATORBUG-485
しかし、これに対する回答は「qmakeはちょっと制限あるから今回のケース(ビルドログを見たら qmake に渡すプロジェクトファイルのパスが Volume{###}\to\the\project\foo.pro のようになってて、qmakeがエラーになってる)は無理だよー」 というちょっと論点のずれたもので、そのままこのissueは何の解決・回避案も出さずにcloseされてしまってる。

これと関連してそうなissue QTBUG-5900 が去年の11月に登録されてる。
こちらは、 QFileInfo::canonicalFilePath() がおかしな値を返すという問題で、Qt 4.7.0 で修正されているらしい。

Qt Creator 1.3は(多分)Qt 4.6系を使って作られているので、 QTBUG-5900 をもろに受けて、qmakeに渡すプロジェクトファイルのパスがおかしくなってるんじゃないかと思う。 ということで、Qt 4.7.0 (現在はbetaalpha1) とそれを使って作られているであろう Qt Creator 2.0 を使えばこの症状は治るのかな。
と、期待しておこう。 今は試せないので、後で試す。

2010-03-26T21:42 追記: Qt Creator 2.0 Tech Preview (alpha1) を入れてもダメでした。 Qt 4.7.0 Tech Preview を入れるとどうだろう..

mingw32-g++ 3.x でQt4 (4.6.2) プロジェクトのビルドをしようとすると、
undefined reference to '_Unwind_Resume'
というエラーが発生する。

対処法は、 http://bugreports.qt.nokia.com/browse/QTBUG-7743?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
の通り。

  • Qt4 のライブラリをビルドしてるのが、g++ 4.4 なので、 mingw32-g++ 4.4 以降を使う。
  • もしくは、Qt4のライブラリをビルドしなおす (<インストールDir>/Qt で qmake projects.pro && make するのかな?)

先日見つけた、tokenize処理のC++コード(元のコードの酷さを壊さない程度に整えてある)

void tokenize(
    std::vector< std::string >& result,
    const std::string& input,
    const char         delimiter
    )
{
  char*	buf = new (std::nothrow) char[ input.size() + 1 ] ;
  assert( buf != 0 ) ;

  buf[0] = '\0' ;
  char*	buf_ptr = buf ;

  for(std::string::const_iterator it = input.begin() ; it != input.end(); ++it ) {
    const char &c = *it;
    if( delimiter  c || '\r'  c || '\t' == c ) {
      *buf_ptr = '\0' ;
      if( buf[0] ) {
        result.push_back( buf );
        buf_ptr = buf ;
      }
    }
    else {
      *buf_ptr++ = *it ;
    }
  }

  *buf_ptr = '\0';
  if( buf[0] ) {
    result.push_back( buf ) ;
  }

  delete[] buf ;
}

関数始まった途端ツッコミどころである。

ていうか、それ Boost String Algorithms Library で出来るよ。とか、Boost使わないまでも、もっとスマートに書けるよね。 と思ったのでちょちょっと書いてみた。

ネタ元→ http://bbs.wankuma.com/index.cgi?mode=al2&namber=38363

ちょろっと.NETのクラスライブラリ眺めてみましたが、 .NETって標準ライブラリ使ってさくっとシャッフルすることって出来ないっぽい?

C++ なら std::random_shuffle, Perl なら List::Util でお手軽にシャッフルできるのにねー

#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
  int list[13];
  for (int i = 0; i < 13; ++i)
    list[i]=i+1;
  std::random_shuffle(list, list+13);
  std::copy(list, list+13, std::ostream_iterator<int>(std::cout, ","));
  return 0;
}
use strict;
use warnings;
use List::Util qw/shuffle/;
$,=',';
print shuffle 1 .. 13

ネタ元: http://twitter.com/hi_saito/status/1524994613
の元ネタ: http://d.hatena.ne.jp/mzp/20090414/hello
のさらに元ネタ: http://d.hatena.ne.jp/Yuichirou/20090414#1239705258

を、見ていたのですが、激しい違和感が...

一番元ネタの設計を日本語で表すと概ね以下のようになると思います。

  1. ようこそ は名前を持っています
  2. ようこそ に喋れ(say)というと "こんにちは"に続いて名前を印字します
  3. オブジェクト指向的HelloWorldとは ようこそ に「世界」という名前を与え、喋らせることです。

何か違わないか?

というわけで、自分なりに オブジェクト指向的HelloWorldを再設計してみた

元ネタは http://code.nanigac.com/forum/view/422 かな。

なんか流行ってるみたいなんでやってみた

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <iterator>
#include <cstring>

char convert(char c, int flg)
{
	return flg ? std::toupper(c) : std::tolower(c);
}

int main(int c, char** v)
{
	if ( c < 2 ) {
		std::cerr << "usage: " << v[0] << " <target string>\n";
		return 0;
	}

	std::string target(v[1]);
	std::vector<int> flg;
	flg.resize(target.size());

	for (int i = 0; i <= target.size(); ++i )
	{
		std::fill_n(flg.rbegin(), i, 1);

		do {
			std::string res;
			std::transform(
					target.begin(), target.end(),
					flg.begin(),
					std::back_inserter(res),
					convert);
			std::cout << res << "\n";
		} while ( std::next_permutation(flg.begin(), flg.end()) );
	}
}

ハノイの塔 をたくさんの言語で。

唐突に書きたくなって、頑張って色々書いてみた。(残念ながらスタック型言語(Brainf*ckとかwhitespaceとかは無い)

ハノイの塔回答プログラムのポイントはおおよそ2点

  • 関数/サブルーチン等の再帰呼び出し処理
  • 経過を出力する際の文字列フォーマッティング

それでは、どうぞ

C++プログラミングの処方箋 をAmazonで購入。(メインの買い物はペンタブの替え芯だったんですが、配送料無料に届かなかったので(ぉ )

通勤時間にちまちま読んでく予定ー (電車乗ってる時間は計20分強しかないですが(汁

その前に詳説正規表現第3版、まだ読み終わってないんだけど、どうしよう...

ネタ元

まず、ふつーに、Cコンパイラの-Iオプションの如く、 -I <path> -I <path> とかやって複数の値を設定するのは下記でできます。

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

int main(int c, char** v)
{
  try {
    namespace po = boost::program_options;

    po::options_description desc("Options");
    desc.add_options()
      ("include,I",  po::value< std::vector<std::string> >(), "include paths")
      ;

    po::variables_map vm;
    po::store(po::parse_command_line(c, v, desc), vm);
    po::notify(vm);    

   if (vm.count("include")) {
      const std::vector< std::string >& v = vm["include"].as< std::vector< std::string > >();
      std::copy(v.begin(),v.end(),std::ostream_iterator<std::string>(std::cout, ", "));
    }

    return 0;
  } catch ( const std::exception& e ) {
    std::cerr << e.what() << "\n";
    return -1;
  }
}

./exec -I a -I b で a, b が得られます。

ネタ元:笑顔がいっぱい

↑を見てついつい anarchy golf

#include<iostream>
#define P std::cout<<p+"\n"
main(){std::string p=":\n:-";P;p=":-)";P;while((p+="))").size()<66)P;}

ちなみに ↑ 投稿時の結果が ↓ です。

RankUserSizeTimeDateStatistics
5turugina1180.093308/09/04 19:15:200B / 62B / 50B

1位の人のサイズが97とか、すごく気になる...

第20回国際情報オリンピック の第1問(TYPE PRINTER) を、 制限とか関係なく 解いてみた。

トップページが寂しくなってきたのでとりあえず投下

さて、どうやりましょ。ビギナなら

void func(int cond)
{
  int n;
  if ( cond )
    n = 0;
  else
    n = 1;
}

なんてのもありですかね。しかしこの程度なら3項演算子を使って

void func(int cond)
{
  int n = cond ? 0 : 1;
}

の方がスマートですね。しかし条件が複雑になってくると3項演算子では読みにくくなるので、前者の方がよいかもです。

インスパイア元 -> オブジェクトじゃんけん
の更にネタ元 -> 勝手にじゃんけん祭り

やっぱC++っつったらtemplateですよねー

今度は template を使って フィボナッチ数列 を求めてみます。

Fibonacci 数列は

F0 = 1, F1 = 1
Fn+2 = Fn + Fn+1 (n≥0)

なので

コラッツの問題 (Collatz・角谷予想) の f(n) を Loki を使って求めてみる。

これのC++版です。LLじゃないけど
特に変わったことはしてないけど、
h(100000)の計算が約0.3秒ですむという驚異。やはりC++、すばらしい(´▽`ノ
#include <iostream>
#include <algorithm> //max_element
#include <map>
#include <cstdlib> // atoi

typedef std::map<int,int> xs_t;

int g(int n) {
  return ( n == 1 ) ? 1 : 1 + g((n%2) ? n*3+1 : n/2);
}

int s(const xs_t::value_type& lhs, const xs_t::value_type& rhs) {
  return lhs.second < rhs.second;
}

int h(int n) {
  xs_t xs;
  for (int i = 0; i < n; ++i) {
    xs[i+1]=g(i+1);
  }
  return std::max_element(xs.begin(), xs.end(), s)->first;
}

int main(int argc, char** argv) {
  int n = ( argc > 1) ? std::atoi(argv[1]) : 100;
  std::cout << "h(" << n << ")=" << h(n) << std::endl;
  return 0;
}
[追記]
せっかくなのでLL2006の方にトラックバックしておきます :D
無駄にC++の機能を使ってCDドライブ排出プログラムを書いてみた。
元々はDeviceIoControl APIの使い方を調べてたんだけど.. まぁいいか

#include <windows.h>
#include <winioctl.h>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <string>

class CdromDriveEnumerator : public std::iterator<std::input_iterator_tag, const std::string>
{
  DWORD dwDrives_;
  int index_;
  std::string drive_;

  public:
  CdromDriveEnumerator()
    : dwDrives_(GetLogicalDrives() << 1), index_(-1), drive_()
    {++(*this);}

  CdromDriveEnumerator(const CdromDriveEnumerator& x)
    : dwDrives_(x.dwDrives_), index_(x.index_), drive_(x.drive_)
    {}

  CdromDriveEnumerator& operator =(const CdromDriveEnumerator& x)
  {
    dwDrives_ = x.dwDrives_;
    index_ = x.index_;
    drive_ = x.drive_;
    return *this;
  }

  reference operator *() const
  {
    return drive_;
  }

  pointer operator ->() const
  {
    return &drive_;
  }

  CdromDriveEnumerator& operator ++()
  {
    ++index_;
    dwDrives_ >>= 1;
    if ( dwDrives_ & 1 ) {
      drive_ = std::string(1, static_cast<char>('A'+index_)).append(":");
      if ( GetDriveType(drive_.c_str()) != DRIVE_CDROM ) {
        ++(*this);
      }
    }
    else {
      ++(*this);
    }
    return *this;
  }

  CdromDriveEnumerator operator ++(int)
  {
    CdromDriveEnumerator ret = *this;
    ++(*this);
    return ret;
  }

  private:
  CdromDriveEnumerator(char drive)
    : dwDrives_(0), index_(0), drive_(std::string(1, drive).append(":"))
    {}

  public:
  static const CdromDriveEnumerator& end() {
    static CdromDriveEnumerator end('Z'+1);
    return end;
  }
};
bool operator ==(const CdromDriveEnumerator& x, const CdromDriveEnumerator& y)
{
  return *x == *y;
}
bool operator !=(const CdromDriveEnumerator& x, const CdromDriveEnumerator& y)
{
  return !(x == y);
} 

struct DriveEjector : public std::unary_function<const std::string&, int>
{
  result_type operator()(argument_type drive) {
    std::cout << "try to eject " << drive << std::endl;

    HANDLE h = CreateFile(
        std::string("\\\\.\\").append(drive).c_str(),
        GENERIC_READ,
        FILE_SHARE_READ,
        0,
        OPEN_EXISTING,
        0,
        0);

    if ( h == INVALID_HANDLE_VALUE ) {
      std::cerr << "failed to open volume \\\\.\\" << drive << std::endl;
      return 1;
    }

    DWORD dwReturned;
    for ( int i = 0; i < 20; ++i ) {
      if ( DeviceIoControl(h, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, &dwReturned, 0) ) {
        if ( DeviceIoControl(h, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0, &dwReturned, 0) ) {
          PREVENT_MEDIA_REMOVAL pmr;
          pmr.PreventMediaRemoval = FALSE;
          if ( DeviceIoControl(h, IOCTL_STORAGE_MEDIA_REMOVAL, 
                &pmr, sizeof(PREVENT_MEDIA_REMOVAL), 0, 0, &dwReturned, 0) ) {
            if ( DeviceIoControl(h, IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, &dwReturned, 0) ) {
              std::cout << "EJECT!" << std::endl;
            }
            break;
          }
        }
      }
    }

    CloseHandle(h);
    return 0;
  }
};

int main()
{
  std::for_each(CdromDriveEnumerator(), CdromDriveEnumerator::end(), DriveEjector());
  return 0;
}

AUTHOR

  • turugina (虎王 剱奈)
  • E-mail: turugina {at} floralcompany.jp
  • pixiv
  • ニジエ

2014年5月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.2.10

- 警 告 -

本サイトにはいわゆる「18禁画像」(イラスト)へのリンクが存在します。 未成年の方や、その手の画像に不快感を覚える方は、 該当記事(「えちぃの」及び「ちょっとえちぃの」カテゴリ) をご覧にならないようお願いいたします。

上記を理解した上で非表示のブログパーツを表示する
あわせて読みたいブログパーツ
ついった
drawr/pixiv/twitpic