ちょっとした処理を行う関数,クラス(C,C++)



ストリーム出力

テキストファイルへも同時に出力するカスタムストリーム出力

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
#include <iostream>
#include <fstream>
#include <sstream>
 
template<typename T>
inline std::string RX_TO_STRING(const T &x)
{
    std::stringstream ss;
    ss << x;
    return ss.str();
}
 
class rxLog
{
    std::fstream m_ofLog;
public:
 
    rxLog(const char *filename)
    {
        m_ofLog.open(filename, std::ios::out);
        if(!m_ofLog || !m_ofLog.is_open() || m_ofLog.bad() || m_ofLog.fail()){
            return;
        }
    }
    ~rxLog()
    {
        if(m_ofLog && m_ofLog.is_open()) m_ofLog.close();
    }
 
        template<typename T>
    rxLog& operator<<(const T &a)
    {
        std::cout << a;
        if(m_ofLog) m_ofLog << RX_TO_STRING(a);
        return *this;
    }
 
        typedef std::basic_ostream<char, std::char_traits<char> > TypeCout;
 
            rxLog& operator<<(TypeCout& (*manip)(TypeCout&))
    {
        manip(std::cout);
        if(m_ofLog) m_ofLog << std::endl;
        return *this;
    }
};
 
static rxLog RXCOUT("test.log");

数値や文字列の出力だけならば<<オペレータのオーバーロードだけでよいが, endlにも対応させるために追加の<<オペレータを定義している.

使用例:

RXCOUT << "x = " << x << std::endl;

ヘルプテキスト表示サンプル

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
void help(void)
{
    static const char* help = "[help]\n"
        " ESC : quit the program\n"
        " 's' : toggle animation on/off\n"
        " Shift+'f' : toggle fullscreen mode\n"
        " 'h' : show this help";
    std::cout << help << std::endl;
}

テキストストリーム

テキストファイルストリームを開く

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15

static inline int OpenFileStream(fstream &file, const string &path, int rw = 1)
{
    file.open(path.c_str(), (rw & 0x01 ? ios::in : 0)|(rw & 0x02 ? ios::out : 0));
    if(!file || !file.is_open() || file.bad() || file.fail()){
        return 0;
    }
    return 1;
}

テキストファイルから文字列リストを読み込む

空行やコメント行を除いて,各行を文字列として配列に格納する.

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67

static inline int ReadTextStream(fstream &file, vector<string> &lines)
{
    int k = 0;
    string buf;
    string::size_type comment_start = 0;
    while(!file.eof()){
        getline(file, buf);
 
                if( (comment_start = buf.find('%')) != string::size_type(-1) ){
            buf = buf.substr(0, comment_start);
        }
 
                if( (comment_start = buf.find("//")) != string::size_type(-1) ){
            buf = buf.substr(0, comment_start);
        }
 
                if( (comment_start = buf.find("#")) != string::size_type(-1) ){
            buf = buf.substr(0, comment_start);
        }
 
                size_t stpos;
        while((stpos = buf.find_first_of()) == 0){
            buf.erase(buf.begin());
            if(buf.empty()) break;
        }
 
                if(buf.empty()){
            continue;
        }
 
        lines.push_back(buf);
        k++;
    }
 
    return k;
}
 

static inline int ReadTextStream(const string path, vector<string> &lines)
{
    fstream file;
    file.open(path.c_str(), ios::in);
    if(!file || !file.is_open() || file.bad() || file.fail()){
        return 0;
    }
    int nlines = ReadTextStream(file, lines);
    file.close();
    return nlines;
}

ビット演算

2進数文字列の生成

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15

string GetBitArray(int x, int bit)
{
    string s;
    s.resize(bit, '0');
    for(int i = 0; i < bit; ++i){
        s[bit-i-1] = ((x >> i) & 0x01) ? '1' : '0';
    }
    return s;
}

ビット演算によるフラグ管理

  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
 32
 33
 34
 35
 36
 37
 38
 39
enum
{
    RX_BIT_A = 0x0001, 
    RX_BIT_B = 0x0002, 
    RX_BIT_C = 0x0004, 
    RX_BIT_D = 0x0008, 
    RX_BIT_E = 0x0010, 
 
    RX_ALL = 0xffff,
};
 
int main(void)
{
    int flag = 0;                    // 00000
 
        flag |= RX_BIT_B;                // 00010
    flag |= (RX_BIT_A | RX_BIT_D);    // 01011
 
        flag &= ~RX_BIT_B;                // 01001
    flag &= ~(RX_BIT_A | RX_BIT_D);    // 00000
 
        flag ^= RX_BIT_E;                // 10000
 
        flag ^= RX_ALL;                    // 01111
 
        if(flag & RX_BIT_A) cout << "A";
    if(flag & RX_BIT_B) cout << "B";
    if(flag & RX_BIT_C) cout << "C";
    if(flag & RX_BIT_D) cout << "D";
    if(flag & RX_BIT_E) cout << "E";
    cout << endl;                    // ABCD
 
    return 0;
}

画面出力

可変引数リストを用いたカスタム版printf

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
#include <stdarg.h>
 
struct Vec2
{
    double data[2];
    double& operator[](int i){ return data[i]; }
};
 
struct Vec3
{
    double data[3];
    double& operator[](int i){ return data[i]; }
};
 

bool FPrintf(const string fn, const string mode, char *fmt, ...)
{
    FILE* fp;
    if((fp = fopen(fn.c_str(), mode.c_str())) == NULL){
        return 0;
    }
 
    va_list ap;            char *p, *sval;
    int ival;
    double dval;
    Vec2 v2val;
    Vec3 v3val;
 
    va_start(ap, fmt);        for(p = fmt; *p; ++p){
        if(*p != '%'){
            putc(*p, fp);
            continue;
        }
        switch(*(++p)){
        case 'd':
            ival = va_arg(ap, int);
            fprintf(fp, "%d", ival);
            break;
        case 'f':
            dval = va_arg(ap, double);
            fprintf(fp, "%f", dval);
            break;
        case 's':
            for(sval = va_arg(ap, char*); *sval; ++sval)
                putc(*sval, fp);
            break;
        case 'v':
            switch(*(++p)){
            case '2':
                v2val = va_arg(ap, Vec2);
                fprintf(fp, "(%f, %f)", v2val[0], v2val[1]);
                break;
            case '3':
                v3val = va_arg(ap, Vec3);
                fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val[2]);
                break;
            default:
                v3val = va_arg(ap, Vec3);
                fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val[2]);
                break;
            }
            break;
        default:
            putc(*p, fp);
            break;
        }
    }
    va_end(ap);
 
    //char *n = "\n";
    //putc(*n, fp);
 
    fclose(fp);
    return true;
}

例えば,

  1
  2
  3
  4
  5
  6
  7
  8
    int i = 123;
    double x = 4.56;
    Vec2 v2;
    v2[0] = 7.8; v2[1] = 9.0;
    Vec3 v3;
    v3[0] = 1.0; v3[1] = 2.0; v3[2] = 3.0;
    Printf("test.txt", "w", "%s : %d, %f\n", "val", i, x);
    Printf("test.txt", "a", "vec : %v2, %v3\n", v2, v3);

のようなコードを実行すると,test.txtが作られて,

val : 123, 4.560000
vec : (7.800000, 9.000000), (1.000000, 2.000000, 3.000000)

が書き込まれる.

コマンドプロンプトに表示すると共にログファイルにも保存(要boost)

  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
#include <boost/iostreams/stream.hpp>
#include <boost/algorithm/string.hpp>
 
class rxCout : public boost::iostreams::sink
{
    string m_strLog;
 
public:
    rxCout(string fn)
    {
        m_strLog = fn;
    }
 
    std::streamsize write(const char* s, std::streamsize n)
    {
        string str;;
        str.resize(n);
        for(int i = 0; i < n; ++i){
            str[i] = s[i];
        }
 
        cout << str;
 
        boost::algorithm::replace_all(str, "\n", "");
 
        static std::ofstream fout(m_strLog, std::ios::out);
        fout << str << endl;
        return n;
    }
};

使うときは,

static boost::iostreams::stream<rxCout> RXCOUT("_log.txt");

などとして,

RXCOUT << "test" << endl;

として用いる.

vector関連

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
template<typename T>
inline std::ostream &operator<<(std::ostream &out, const vector<T> &x)
{
    for(size_t i = 0; i < x.size(); ++i){
        out << x[i] << (i == x.size()-1 ? "" : ", ");
    }
    return out;
}
 

template<class T> 
inline void EraseSTLVectori(vector<T> &src, int idx)
{
    src.erase(src.begin()+idx);
}
 

template<class T> 
inline int EraseSTLVector(vector<T> &src, boost::function<bool (T)> comp_func)
{
    int cnt = 0;
    vector<T>::iterator itr = src.begin();
    while(itr != src.end()){
        if(comp_func(*itr)){
            itr = src.erase(itr);
            cnt++;
        }
        else{
            ++itr;
        }
    }
 
    return cnt;
}

配列

ランダムシャッフル

STLのalgorithmのrandom_shuffle (algorithm#zf86514c参照)の存在に気づく前に作ったもの.

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42

template<typename T>
inline void RandomSort(T arr[], int n)
{
    int rnd;
    T temp;
 
    srand(time(NULL));
 
    for(int i = 0; i < n; ++i){
        rnd = rand()%n;
        temp = arr[i];
        arr[i] = arr[rnd];
        arr[rnd] = temp;
    }
}
 

template<typename T>
inline void RandomSortV(vector<T> &arr)
{
    int n = (int)arr.size();
    int rnd;
    T temp;
 
    srand(time(NULL));
 
    for(int i = 0; i < n; ++i){
        rnd = rand()%n;
        temp = arr[i];
        arr[i] = arr[rnd];
        arr[rnd] = temp;
    }
}

ファイル処理

フォルダ生成

処理系に依存して使えない場合あり.

  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
 32
 33
 34
 35
 36
 37
 38
#include <direct.h>
 

static int MkDir(string dir)
{
    if(_mkdir(dir.c_str()) != 0){
        char cur_dir[512];
        _getcwd(cur_dir, 512);            if(_chdir(dir.c_str()) == 0){                cout << "MkDir : " << dir << " is already exist." << endl;
            _chdir(cur_dir);                return 1;
        }
        else{
            size_t pos = dir.find_last_of("\\/");
            if(pos != string::npos){                    int parent = MkDir(dir.substr(0, pos+1));                    if(parent){
                    if(_mkdir(dir.c_str()) == 0){
                        return 1;
                    }
                    else{
                        return 0;
                    }
                }
            }
            else{
                return 0;
            }
        }
    }
 
    return 1;
}

ファイル名生成

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51

inline string GetFileNameWithExt(const string &fn, const string &ext)
{
    string new_fn = fn;
 
    size_t pos1 = fn.rfind('.');
    if(pos1 != string::npos){
        new_fn = fn.substr(0, pos1);
    }
 
    return new_fn+"."+ext;
}
 

inline string CreateFileName(const string &head, const string &ext, int n, const int &d)
{
    string file_name = head;
    int dn = d-1;
    if(n > 0){
        dn = (int)(log10((double)n))+1;
    }
    else if(n == 0){
        dn = 1;
    }
    else{
        n = 0;
        dn = 1;
    }
 
    for(int i = 0; i < d-dn; ++i){
        file_name += "0";
    }
 
    file_name += boost::lexical_cast<std::string>(n);
    file_name += ".";
    file_name += ext;
 
    return file_name;
}

ファイル探索

boost::filesystem使用版

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
#include <boost/function.hpp>
 
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
 

static void SearchFiles(const boost::filesystem::path &dpath, vector<string> &paths)
{
        boost::filesystem::directory_iterator end; 
    for(boost::filesystem::directory_iterator it(dpath); it!=end; ++it){
        if(boost::filesystem::is_directory(*it)){
            SearchFiles(it->path(), paths);
        }
        else{
            paths.push_back(it->path().file_string());
        }
    } 
}
 

static void SearchFiles(const boost::filesystem::path &dpath, vector<string> &paths, boost::function<bool (string)> fpComp)
{
        boost::filesystem::directory_iterator end; 
    for(boost::filesystem::directory_iterator it(dpath); it!=end; ++it){
        if(boost::filesystem::is_directory(*it)){
            SearchFiles(it->path(), paths);
        }
        else{
            string fpath = it->path().file_string();
            if(fpComp(fpath)){
                paths.push_back(fpath);
            }
        }
    }
}
 
 

static bool FindFile(const boost::filesystem::path &dpath, const std::string &fname, boost::filesystem::path &found_path)
{
    if(!boost::filesystem::exists(dpath)) return false;
 
    boost::filesystem::directory_iterator end_itr;
    for(boost::filesystem::directory_iterator itr(dpath); itr != end_itr; ++itr){
        if(boost::filesystem::is_directory(itr->status())){
            if(FindFile(itr->path(), fname, found_path)) return true;
        }
        else if(itr->leaf() == fname){
            found_path = itr->path();
            return true;
        }
    }
    return false;
}
 

inline bool SearchCompExt(const string &fn, const string &ext)
{
    return (fn.find(ext, 0) != string::npos);
}

Windows API使用版.RX_S2W,RX_W2Sはプロジェクトの設定でUnicode文字セットを使用している場合のみ必要. マルチバイト文字セットにしている場合は必要なし.

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
#include <cstdlib>
#include <windows.h>
#include <tchar.h>
 
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
 

inline static std::string RX_W2S(const std::wstring &src)
{
    char *mbs = new char[src.length() * MB_CUR_MAX + 1];
    wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);
    std::string dst = mbs;
    delete [] mbs;
    return dst;
}
 

inline static std::wstring RX_S2W(const std::string &src)
{
    wchar_t *wcs = new wchar_t[src.length() + 1];
    mbstowcs(wcs, src.c_str(), src.length() + 1);
    std::wstring dst = wcs;
    delete [] wcs;
    return dst;
}
 
 

static void SearchFiles(const std::string &dpath, std::vector<std::string> &paths, int d, const int n, 
                        const std::vector<std::string> &exts)
{
    HANDLE handle;
    WIN32_FIND_DATA fd;
 
    // search first file with the wildcard "*" to find the all type of file
    handle = FindFirstFile(RX_S2W(dpath+"\\*").c_str(), &fd);
 
    // if fail to find the file
    if(handle == INVALID_HANDLE_VALUE){
        return;
    }
 
    // search next files
    do{
        // file name
        std::string name = RX_W2S(static_cast<LPCTSTR>(fd.cFileName));
        std::string fpath = dpath+"\\"+name;
 
		if(name == "." || name == "..

ファイルの存在確認

boost::filesystemを用いた場合,

  1
  2
  3
  4
  5
  6
  7
  8
  9

bool ExistFile(const string &path_str)
{
    fspath fnph(path_str);
    return boost::filesystem::exists(fnph);
}

fopenを用いる場合,

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
int FileExist(const char *fn)
{
    FILE *fp;
 
    if( (fp = fopen(fn, "r")) == NULL ){
        return 0;
    }
 
    fclose(fp);
    return 1;
}

fstreamでバイナリファイルの読み書き

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
#include <iostream>
#include <fstream>
#include <sstream>
 
#include <cstdlib>
 
using namespace std;
 
int main(void)
{
    srand(12345);
 
        const int N = 10;
    double a[N];
    for(int i = 0; i < N; ++i) a[i] = rand()/(double)RAND_MAX;
 
        ofstream fout;
    fout.open("binary_test.dat", ios::out|ios::binary);        if(!fout){
        cout << "file couldn't open." << endl;
        return 1;
    }
 
    for(int i = 0; i < N; ++i){
        //fout << a[i];
        fout.write((char*)&a[i], sizeof(double));
        cout << a[i] << ", ";        }
    cout << endl;
 
    fout.close();
 
        ifstream fin;
    fin.open("binary_test.dat", ios::in|ios::binary);        if(!fin){
        cout << "file couldn't find." << endl;
        return 1;
    }
 
    double x;
    for(int i = 0; i < N; ++i){
        //fin >> x;
        fin.read((char*)&x, sizeof(double));
        cout << x << ", ";        }
    cout << endl;
 
    fin.close();
 
        fin.open("binary_test.dat", ios::in|ios::binary);        if(!fin){
        cout << "file couldn't find." << endl;
        return 1;
    }
 
    int j = 3;
    fin.seekg(j*sizeof(double));        fin.read((char*)&x, sizeof(double));
    cout << j << " : " << x << endl;
 
    fin.close();
}

数字処理

数字の桁数を数える

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18

inline int CountDigit(int n)
{
    int d = 0;
    if(n > 0){
        return (int)(log10((double)n))+1;
    }
    else if(n == 0){
        return 1;
    }
    else{
        return (int)(log10((double)(-n)))+1;
    }
}

整数値の下一桁の値を抽出

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

inline int ExtractLastDigit(const int &x)
{
    int x1 = (x < 0) ? -x : x;
    return x1-(int)(x1/10)*10;
}

整数値の任意桁の値を抽出

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17

inline int ExtractAnyDigit(const int &x, const int &d)
{
    if(d <= 0) return 0;
 
    int x1 = (x < 0) ? -x : x;
    int c = (int)log((double)x1);        if(d > c) return 0;
 
    int a = (int)pow(10.0, (double)d);    // 10^d
    return (x1-(int)(x1/a)*a)/(a/10);
}

0付き数字の生成

  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

inline string GenZeroNo(int n, const int &d)
{
    string zero_no = "";
    int dn = d-1;
    if(n > 0){
        dn = (int)(log10((double)n))+1;
    }
    else if(n == 0){
        dn = 1;
    }
    else{
        n = 0;
        dn = 1;
    }
 
    for(int i = 0; i < d-dn; ++i){
        zero_no += "0";
    }
 
    zero_no += boost::lexical_cast<std::string>(n);
 
    return zero_no;
}

時間計測

ストップウォッチクラス

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include <iostream>
 
#include <vector>
#include <string>
 
#define RX_USE_MM
#ifdef WIN32
    #include <windows.h>
 
    #ifdef RX_USE_MM
    #include <mmsystem.h>
    #pragma comment (lib, "winmm.lib")
    #endif
 #endif
 
#ifdef WIN32
    #ifdef RX_USE_MM
        #define RXTIME DWORD
        #define RXGETTIME timeGetTime
        #define RXTIME2SEC 1.0e-3
        //#define RXTIME2SEC 1.0
    #else
        #define RXTIME DWORD
        #define RXGETTIME GetTickCount
        #define RXTIME2SEC 1.0e-3
        //#define RXTIME2SEC 1.0
    #endif
#else
    #define RXTIME clock_t
    #define RXGETTIME clock
    #define RXTIME2SEC (1.0/CLOCKS_PER_SEC)
#endif
 
 
using namespace std;
 
 
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class rxTimer
{
    RXTIME m_tStart, m_tEnd;
    vector<double> m_vTimes;
    vector<string> m_vComments;
 
public:
        rxTimer(){}
 
        ~rxTimer(){}
 
        void Start(void)
    {
        m_tStart = RXGETTIME();
    }
 
        void Split(const string &cmnt = "", bool restart = false)
    {
        m_tEnd = RXGETTIME();
 
        double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
        m_vTimes.push_back(time);
        m_vComments.push_back(cmnt);
 
        if(restart) m_tStart = RXGETTIME();
    }
 
        void Stop(const string &cmnt = "")
    {
        m_tEnd = RXGETTIME();
 
        double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
        m_vTimes.push_back(time);
        m_vComments.push_back(cmnt);
 
        m_tStart = m_tEnd = 0;
    }
 
        void Reset(void)
    {
        m_vTimes.clear();
        m_vComments.clear();
        m_tStart = m_tEnd = 0;
    }
 
        void PopBackTime(void)
    {
        m_vTimes.pop_back();
        m_vComments.pop_back();
    }
 
        void SetTime(const double &t, const string &cmnt = "")
    {
        m_vTimes.push_back(t);
        m_vComments.push_back(cmnt);
    }
 
        double GetTime(int i)
    {
        if(i >= (int)m_vTimes.size()) return 0.0;
 
        return m_vTimes[i];
    }
 
        int GetTimeNum(void)
    {
        return (int)m_vTimes.size();
    }
 
        double Print(void)
    {
        int m = 0, mi;
        if(m_vTimes.empty()){
            return 0.0;
        }
        else{
                        double total = 0.0;
            for(int i = 0; i < (int)m_vTimes.size(); ++i){
                mi = (int)m_vComments[i].size();
                if(mi > m) m = mi;
 
                total += m_vTimes[i];
            }
 
            SetTime(total, "total");
        }
 
        int cur_p = cout.precision();
        cout.precision(3);
        cout.setf(ios::fixed);
        for(int i = 0; i < (int)m_vTimes.size(); ++i){
            string spc;
            for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) spc += " ";
            cout << m_vComments[i] << spc << " : " << m_vTimes[i] << endl;
        }
        cout.unsetf(ios::fixed);
        cout.precision(cur_p);
 
        double t = m_vTimes.back();
 
        PopBackTime();  
        return t;
    }
 
        double PrintToString(string &str)
    {
        int m = 0, mi;
        if(m_vTimes.empty()){
            return 0.0;
        }
        else{
                        double total = 0.0;
            for(int i = 0; i < (int)m_vTimes.size(); ++i){
                mi = (int)m_vComments[i].size();
                if(mi > m) m = mi;
 
                total += m_vTimes[i];
            }
 
            SetTime(total, "total");
        }
 
        stringstream ss;
        ss.precision(3);
        ss.setf(ios::fixed);
        
        int n = (int)m_vTimes.size();
        for(int i = 0; i < n; ++i){
            string spc;
            for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) spc += " ";
            ss << m_vComments[i] << spc << " : " << m_vTimes[i] << "\n";
        }
 
        ss << "\n";
        str = ss.str();
 
        double t = m_vTimes.back();
 
        PopBackTime();  
        return t;
    }
};

平均値の計測

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
class rxTimerAvg
{
public:
        struct rxTimeAndCount
    {
        double time;
        int count;
        int idx;
    };
 
        typedef map<string, rxTimeAndCount> RXMAPTC;
 
private:
    rxTimer m_Tmr;            RXMAPTC m_TimeMap;     
public:
        rxTimerAvg()
    {
        Clear();
        ResetTime();
        ClearTime();
    }
 
    
    void Clear(void)
    {
        m_TimeMap.clear();
    }
 
    
    void ClearTime(void)
    {
        for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
            it->second.time = 0.0;
            it->second.count = 0;
            //it->second.idx = -1;
        }
    }
 
    
    void ResetTime(void)
    {
        m_Tmr.Reset();
        m_Tmr.Start();
    }
 
    
    void Split(const string &cmnt)
    {
        RXMAPTC::iterator i = m_TimeMap.find(cmnt);
        
        m_Tmr.Stop();
        if(i == m_TimeMap.end()){
            
            m_TimeMap[cmnt].time = m_Tmr.GetTime(0);
            m_TimeMap[cmnt].count = 1;
            m_TimeMap[cmnt].idx = m_TimeMap.size()-1;
        }
        else{
            m_TimeMap[cmnt].time += m_Tmr.GetTime(0);
            m_TimeMap[cmnt].count++;
        }
        m_Tmr.Reset();
        m_Tmr.Start();
    }
 
    
    double GetTotalTime(void)
    {
        if(m_TimeMap.empty()){
            m_Tmr.Stop();
            return m_Tmr.GetTime(0);
        }
        else{
            double total = 0.0;
            for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
                total += it->second.time/it->second.count;
            }
 
            return total;
        }
    }
 
    
    void Print(void)
    {
        int m = 0, mi;
        double total = 0.0;
        for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
            mi = (int)it->first.size();
            if(mi > m) m = mi;
 
            total += it->second.time/it->second.count;
        }
 
        int cur_p = cout.precision();
        cout.precision(3);
        cout.setf(ios::fixed);
        for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
            string spc = RXFunc::GenSpace( m-(int)(it->first.size()) );
 
            RXCOUT << it->first << spc << " : " << (it->second.time/it->second.count) << "[s]" << endl;
        }
        cout.unsetf(ios::fixed);
        cout.precision(cur_p);
 
        string spc = RXFunc::GenSpace(m-5);
        RXCOUT << "total" << spc << " : " << total << endl;
    }
 
    
    void PrintToString(string &str)
    {
        int m = 0, mi;
        double total = 0.0;
        for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
            mi = (int)it->first.size();
            if(mi > m) m = mi;
 
            total += it->second.time/it->second.count;
        }
 
        stringstream ss;
        ss.precision(3);
        ss.setf(ios::fixed);
        for(int i = 0; i < (int)m_TimeMap.size(); ++i){
            RXMAPTC::iterator it = m_TimeMap.begin();
 
            for(it = m_TimeMap.begin(); it != m_TimeMap.end(); ++it){
                if(it->second.idx == i){
                    break;
                }
            }
 
            string spc = RXFunc::GenSpace(m-(int)(it->first.size()));
            ss << it->first << spc << " : " << (it->second.time/it->second.count) << "[s]\n";
        }
 
        string spc = RXFunc::GenSpace(m-5);
        ss << "total" << spc << " : " << total << "[s]\n";
 
        str = ss.str();
    }
};

現在時刻の取得

  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
 32
#include <iostream>
#include <string>
#include <ctime>
 
const std::string WEEK[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
 
int main(void)
{
    time_t timer;
    tm *time_st;
 
        time(&timer);
 
        cout <<  << ctime(&timer) << endl;
 
        time_st = localtime(&timer);
        cout <<  << time_st->tm_year+1900 << "/" << time_st->tm_mon+1 << "/" << time_st->tm_mday << endl;
        cout <<  << time_st->tm_hour << ":" << time_st->tm_min << ":" << time_st->tm_sec << endl;
        cout <<  << WEEK[time_st->tm_wday] << endl;
        cout <<  << time_st->tm_yday << endl;
        cout <<  << time_st->tm_isdst << endl;
 
    return 0;
}

実行結果の例

現在時刻 : Wed Aug 31 13:11:31 2011

日付 : 2011/8/31
時刻 : 13:11:31
曜日 : Wednesday
年間日 : 242
サマータイムラグ : 0

行列

行列とベクトルの積

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65

template<class T> 
inline void MulMatVec4(T d[4], const T m[4][4], const T v[4])
{
    d[0] = (v[0]*m[0][0]+v[1]*m[0][1]+v[2]*m[0][2]+v[3]*m[0][3]);
    d[1] = (v[0]*m[1][0]+v[1]*m[1][1]+v[2]*m[1][2]+v[3]*m[1][3]);
    d[2] = (v[0]*m[2][0]+v[1]*m[2][1]+v[2]*m[2][2]+v[3]*m[2][3]);
    d[3] = (v[0]*m[3][0]+v[1]*m[3][1]+v[2]*m[3][2]+v[3]*m[3][3]);
}
 

template<class T> 
inline void MulVecMat4(T d[4], const T v[4], const T m[4][4])
{
    d[0] = (v[0]*m[0][0]+v[1]*m[1][0]+v[2]*m[2][0]+v[3]*m[3][0]);
    d[1] = (v[0]*m[0][1]+v[1]*m[1][1]+v[2]*m[2][1]+v[3]*m[3][1]);
    d[2] = (v[0]*m[0][2]+v[1]*m[1][2]+v[2]*m[2][2]+v[3]*m[3][2]);
    d[3] = (v[0]*m[0][3]+v[1]*m[1][3]+v[2]*m[2][3]+v[3]*m[3][3]);
}
 

template<class T> 
inline void MulMatVec(T *d, T **m, T *v, int n)
{
    for(int i = 0; i < n; ++i){
        d[i] = (T)0;
        for(int j = 0; j < n; ++j){
            d[i] += v[j]*m[i][j];
        }
    }
}
 

template<class T> 
inline void MulVecMat(T *d, T *v, T **m, int n)
{
    for(int i = 0; i < n; ++i){
        d[i] = (T)0;
        for(int j = 0; j < n; ++j){
            d[i] += v[j]*m[j][i];
        }
    }
}

行列の画面出力

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75

static void PrintMatrix(string header, double *matrix, int nx, int ny)
{
    int n = (int)header.size();
 
    string disp = "%f ";
    for(int j = 0; j < ny; ++j){
        if(j == 0){
            printf("%s", header.c_str());
        }
        else{
            for(int k = 0; k < n; ++k) printf(" ");
        }
        printf("| ");
        for (int i = 0; i < nx; ++i){
            printf(disp.c_str(), matrix[j*nx+i]); 
        }
        printf(" |\n");
    }
//    printf("\n");
}
 

static void FPrintMatrix(FILE *fp, string header, double *matrix, int nx, int ny)
{
    int n = (int)header.size();
 
    string disp = "%f ";
    for(int j = 0; j < ny; ++j){
        if(j == 0){
            fprintf(fp, "%s", header.c_str());
        }
        else{
            for(int k = 0; k < n; ++k) fprintf(fp, " ");
        }
        fprintf(fp, "| ");
        for (int i = 0; i < nx; ++i){
            fprintf(fp, disp.c_str(), matrix[j*nx+i]); 
        }
        fprintf(fp, " |\n");
    }
}
 
 

static void OutputMatrix(FILE *fp, int frame, double *matrix, int nx, int ny)
{
    fprintf(fp, "%d ", frame);
    for(int j = 0; j < ny; ++j){
        for (int i = 0; i < nx; ++i){
            fprintf(fp, "%f ", matrix[j*nx+i]); 
        }
    }
    fprintf(fp, "\n");
}

グリッドの線型補間

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline int GET_INDEX(int i, int j, int k, int nx, int ny){ return k*nx*ny+j*nx+i; }
inline int GET_INDEX_2D(int i, int j, int nx){ return j*nx+i; }
 

inline void GRID2D(const double &x, const double &y, const double &dx, const double &dy, const int &nx2, const int &ny2, 
                   int &i0, int &i1, int &j0, int &j1, double &s, double &t)
{
    double x0 = x/dx, y0 = y/dx;
 
        i0 = (int)x0; i1 = i0+1;
    j0 = (int)y0; j1 = j0+1;
 
    s = (x0-i0);
    t = (y0-j0);
 
        if(i0 < 0){
        i0 = 0; i1 = 1;
        s = 0.0;
    }
    if(i1 >= nx2){
        i0 = nx2-2; i1 = nx2-1;
        s = 1.0;
    }
 
        if(j0 < 0){
        j0 = 0; j1 = 1;
        t = 0.0;
    }
    if(j1 >= ny2){
        j0 = ny2-2; j1 = ny2-1;
        t = 1.0;
    }
}
 

inline void GRID3D(const double &x, const double &y, const double &z, const double &dx, const double &dy, const double &dz, 
                   const int &nx, const int &ny, const int &nz, int &i0, int &i1, int &j0, int &j1, int &k0, int &k1, double &s, double &t, double &u)
{
    double x0 = x/dx, y0 = y/dx, z0 = z/dz;
 
    if(x0 < 0.0) x0 = 0.0;
    if(y0 < 0.0) y0 = 0.0;
    if(z0 < 0.0) z0 = 0.0;
 
        i0 = (int)x0; i1 = i0+1;
    j0 = (int)y0; j1 = j0+1;
    k0 = (int)z0; k1 = k0+1;
 
    s = (x0-i0);
    t = (y0-j0);
    u = (z0-k0);
 
        if(i0 < 0){
        i0 = 0; i1 = 1;
        s = 0.0;
    }
    if(i1 > nx+1){
        i0 = nx; i1 = nx+1;
        s = 1.0;
    }
 
        if(j0 < 0){
        j0 = 0; j1 = 1;
        t = 0.0;
    }
    if(j1 > ny+1){
        j0 = ny; j1 = ny+1;
        t = 1.0;
    }
 
        if(k0 < 0){
        k0 = 0; k1 = 1;
        u = 0.0;
    }
    if(k1 > nz+1){
        k0 = nz; k1 = nz+1;
        u = 1.0;
    }
}
 
 

inline double LINEAR_INTERPOLATE_2D(const double &x, const double &y, double *f, const double &dx, const double &dy, const int &nx2, const int &ny2)
{
    int i0, j0, i1, j1;
    double s0, t0, s1, t1;
 
    GRID2D(x, y, dx, dy, nx2, ny2, i0, i1, j0, j1, s1, t1);
 
    s0 = 1.0-s1; 
    t0 = 1.0-t1; 
 
        return s0*(t0*f[GET_INDEX_2D(i0, j0, nx2)]+t1*f[GET_INDEX_2D(i0, j1, nx2)])+
           s1*(t0*f[GET_INDEX_2D(i1, j0, nx2)]+t1*f[GET_INDEX_2D(i1, j1, nx2)]);
}
 

inline double LINEAR_INTERPOLATE_3D(const double &x, const double &y, const double &z, double *f, 
                                    const double &dx, const double &dy, const double &dz, 
                                    const int &nx, const int &ny, const int &nz)
{
    int i0, i1, j0, j1, k0, k1;
    double s0, s1, t0, t1, u0, u1;
 
    GRID3D(x, y, z, dx, dy, dz, nx, ny, nz, i0, i1, j0, j1, k0, k1, s1, t1, u1);
    s0 = 1.0-s1; 
    t0 = 1.0-t1; 
    u0 = 1.0-u1;
 
        return u0*(s0*(t0*f[GET_INDEX(i0, j0, k0, nx+2, ny+2)]+t1*f[GET_INDEX(i0, j1, k0, nx+2, ny+2)])+ \
               s1*(t0*f[GET_INDEX(i1, j0, k0, nx+2, ny+2)]+t1*f[GET_INDEX(i1, j1, k0, nx+2, ny+2)]))+ \
           u1*(s0*(t0*f[GET_INDEX(i0, j0, k1, nx+2, ny+2)]+t1*f[GET_INDEX(i0, j1, k1, nx+2, ny+2)])+ \
               s1*(t0*f[GET_INDEX(i1, j0, k1, nx+2, ny+2)]+t1*f[GET_INDEX(i1, j1, k1, nx+2, ny+2)]));
 
}

データ構造

ラベルとデータのマッピングクラス

stl::mapのラッパ.

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template<class Type> 
class MapData
{
protected:
    map<string, Type> m_Map;        string m_strCurrentMap;         
public:
    
    Type LookupData(const char *name)
    {
        map<string, Type>::iterator i = m_Map.find(name);
 
        if(i == m_Map.end())
            return NULL;
        else
            return m_Map[name];
    }
 
    
    Type GetCurrentData()
    {
        return m_Map[m_strCurrentMap];
    }
 
    
    string GetCurrentLabel()
    {
        return m_strCurrentMap;
    }
 
    
    Type SetCurrentData(const char *name)
    {
        Type data = LookupData(name);
 
        if(data){
            m_strCurrentMap = name;
        }
 
        return data;
    }
 
    
    void CreateData(const char *name, Type data)
    {
        Type data0 = LookupData(name);
 
        if(!data0){
            m_Map[name] = data;
            m_strCurrentMap = name;
        }
    }
 
    
    void Clear(void)
    {
        m_Map.clear();
        m_strCurrentMap = "";
    }
 
    
    void GetStrings(vector<string> &strs)
    {
        map<string, Type>::iterator it;
        for(it = m_Map.begin(); it != m_Map.end(); ++it){
            strs.push_back(it->first);
        }
    }
};

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-11-30 (水) 13:48:11