LoginSignup
1
0

More than 5 years have passed since last update.

バイナリデータ中のランの度数分布をとる

Last updated at Posted at 2018-05-25

はじめてのqiitaへの投稿.

適当なバイナリデータが与えられたときに,「ラン」の度数分布を計算したい.
ランの定義は以下の通り
たとえば 0000110000011111 という文字列を考える
このとき同じ文字が4回,2回,5回,5回と続くので度数分布 h[i] は
h[0]=0, h[1]=0, h[2]=1, h[3]=0, h[4]=1, h[5]=2 となる.

以下はバイナリデータを4バイト区切りで解釈してランの度数分布を求めるための c++ コード

/* run_count.cpp */

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

template<class UINT_T>
int run_count(string filename, int max=256){
  vector<uint32_t> hist(max,0);
  ifstream fin(filename);
  UINT_T buf, prev=max;
  uint32_t run = 0;

  if(!fin){
    cerr << filename << "cannot open" << endl;
    exit(-1);
  }

  bool first = true;
  while(!fin.eof()){
    fin.read((char*)&buf, sizeof(buf));
    if(buf!=prev){
      prev = buf;
      run++;
      if(run>=max){ run = max-1; }
      hist[run] += 1;
      run = 0;
    } else { run++; }
  }
  hist[run] += 1;

  hist[1] -= 1;  // this is to reduce the first dummy run

  for(int i=0;i<max;++i){
    cout << i << " " << hist[i] << endl;
  }
}

int main(){
  cout << "=== test.binary ===" << endl;
  run_count<uint32_t>("test.binary",64);

  cout << "=== toy.binary ===" << endl;
  run_count<uint32_t>("toy.binary",16);
}

適当なデータ生成プログラム

#include <random>
#include <fstream>

using namespace std;

void gen_data(uint32_t len,     // length of the data
              ostream &out      // output stream
              )
{
  uint32_t n, N=0;
  mt19937 gen(0);
  geometric_distribution<uint32_t> rand(0.3);
  int k=0;
  while(true){
    n = rand(gen);
    N += n;
    for(int i=0;i<n;++i){
      out.write((char*)&k, sizeof(uint32_t));
    }
    if(N>len) break;
    k++; k=k%2;
  }
}

void gen_data_toy(ostream &out      // output stream
                  )
{
  vector<int> x = {7,5,4};
  int k=0;

  for(auto xi : x){
    for(int i=0;i<xi;++i){
      out.write((char*)&k, sizeof(uint32_t));
    }
    k++; k=k%2;
  }
}

int main(){
  ofstream out("test.binary");
  gen_data(1000000, out);
  out.close();

  ofstream out2("toy.binary");
  gen_data_toy(out2);
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0