指定した文字列以降を出力するrubyプログラム
指定した文字列以降を出力するrubyプログラムを作成した。
a,b,c,d, ----------------------------- A,B,C,D,
このようなファイルがあったとして、
”-----------------------------”を含めてそれ以降を出力する。
読み込む対象のファイル名は引数で与える。
file=open(ARGV[0]) lines=file.read().split("\n") export=false lines.each do |line| if line =~/-----------------------------/ export=true end if export then puts(line) end end file.close
vectorで指定した値を持つインデックスを複数返す
vec1の要素のうち、targetで指定した値を持つインデックスを複数返す関数を作成した。
vector<int> detectIndex(vector<double> vec1, double target) { vector<int> result; for (auto itr = vec1.begin(); itr != vec1.end(); ++itr) { if (*itr == target) result.push_back(std::distance(vec1.begin(), itr)); } return result; }
バッチファイルでフォルダを作成してから計算実行
このようにフォルダ分けをして計算結果を書き出す場合を考える。
call test.exe >case1/condition1/output.txt call test.exe >case1/condition2/output.txt call test.exe >case1/condition3/output.txt
この場合、case1/condition1等のフォルダが存在しないと実行時にエラーとなる。
これを防ぐため、バッチファイル内で自動でフォルダを作成するように
以下の文をバッチファイルの冒頭に記述した。
mkdir case1 cd case1 mkdir condition1 condition2 condition3 cd ../
フォルダ数が少なければこの方法で対処することができる。
特定の数値が出現するまでRでデータを読み込む
タブ区切りのデータについて。
データが何行あるかわからない場合を考える。
*----------------------* 1 10 100 2 20 200 5 50 500 10 100 1000 *----------------------*
このようなtxtファイルがあるとする。
read.table()で読み込むと
*----------------------*
の部分が悪さをしてエラーが出るため、以下の関数を作成して読み込んだ。
get_i <- function(filename, target){ f<-file(filename,"r") num<-0 for(i in 1:10000){ a<-readLines(con=f,1) if(i>1){ v<-as.vector(as.numeric(strsplit(a,"\t")[[1]])) if(v[1]==target){ return(i) } } } return() }
1行ごとに読み込み、targetとした目的の数値が出たところで読み込みを終了し、
目的の数値が何行目にあるかを返してくる。
今回はskip=1であるから、関数を以下のように使用する。
i<-1 filename<-paste("output",i,".txt",sep="") n<-get_i(filename, 10) data<-read.table(filename,skip=1,nrows=n-1,sep="\t")
C++で複数行のデータを読み込んでひとつのベクトルに格納する
改行を含むコンマ区切りのデータを一つのvectorに格納する場合。
fileの内容は以下の通りでintが6つである。
1,10,100, 2,20,200,
#include <iostream> #include <string> #include <fstream> #include <sstream> using namespace std; class InputManager { private: public: void Get_TxtData(string filename) { ifstream ifs(filename); if (ifs.fail()) cout << "ifs is failed." << endl; string str; vector<int> container; while (getline(ifs, str, ',')){ if (str[0] == '\n') str.erase(str.begin(), str.begin() + 1); container.push_back(stoi(str)); } return; } };
コンマで区切られた各数字がcontainerに数値として格納される。
オブジェクトポインタを使用してクラスを切り替える
OperationManagerを基本クラスとし、それに追加機能をつけるクラスAdditionalManagerを考える。
存在するクラスは以下の2つ。
・OperationManager
・AdditionalManager(これはOperationManagerを継承している)
この時両クラスには同名の関数virtual void func()があるとする。
どちらのクラスのfunc()を呼び出すかをシンプルに切り替える記述は以下の通り。
bool Additional = true; OperationManager *op; if (Additional) op = new AdditionalManager(); else op = new OperationManager(); op->func();
これにより
Additonal=trueの時 AdditionalManagerのfunc()
Additonal=falseの時 OperationManagerのfunc()
が呼び出される
なお、virtual をつけないと基本クラス(今回だとOperationManager)しか呼び出されないことに注意。
コマンドライン引数をまとめて処理する関数の作成
コマンドライン引数をまとめてベクトルに入れておけば、メイン関数をすっきりと書くことができる。
main関数では以下の処理を行う。
vector<string> input; for (int i = 1; i < argc; i++) input.push_back(argv[i]);
この読み込んだinputを別のクラス内でstoiやstodをすればよい。例は以下の通り。
void SetInput(vector<string>& _input) { vector<string> ParaInput; ParaInput = _input; convert_type(ParaInput); } void convert_type(vector<string> ParaInput) { hoge1 = stoi(ParaInput[0]); }