作った動機
競技プログラミングでいつも使う典型をコピペするのも面倒なので、vscodeのスニペット機能を使って、"@(アルゴリズムの名前)"と打てば貼り付けられるようにしたい。
でも、長いコードになるとスニペットにするための書式を調整するのが人間のやることじゃない。。(めっちゃだるい。。)
だから、スニペット用の書式に直すプログラムを書きました。
動き
ライブラリ化したいコード
struct uftree{
int cou;
vector<int> parent;
vector<int> rank;
vector<int> _size;
uftree(int n){
parent=vector<int>(n);
rank=vector<int>(n,0);
_size=vector<int>(n,1);
cou=n;
rep(i,n){
parent[i]=i;
}
}
int root(int i){
return parent[i]==i?i:parent[i]=root(parent[i]);
}
bool same(int i,int j){
return root(i)==root(j);
}
void merge(int i,int j){
i=root(i);j=root(j);
if(i==j)return;
cou--;
if(rank[i]>=rank[j]){
parent[j]=i;
_size[i]+=_size[j];
}else{
parent[i]=j;
_size[j]+=_size[i];
}
if(rank[i]==rank[j])rank[i]++;
return;
}
int count(){
return cou;
}
int unitsize(int i){
return _size[root(i)];
}
};
スニペット化ツールでスニペットの書式に直したもの
"uftree":{
"scope": "cpp",
"prefix": "@uftree",
"body": [
"struct uftree{",
"\tint cou;",
"\tvector<int> parent;",
"\tvector<int> rank;",
"\tvector<int> _size;",
"\tuftree(int n){",
"\t\tparent=vector<int>(n);",
"\t\trank=vector<int>(n,0);",
"\t\t_size=vector<int>(n,1);",
"\t\tcou=n;",
"\t\trep(i,n){",
"\t\t\tparent[i]=i;",
"\t\t}",
"\t}",
"\tint root(int i){",
"\t\treturn parent[i]==i?i:parent[i]=root(parent[i]);",
"\t} ",
"\tbool same(int i,int j){",
"\t\treturn root(i)==root(j);",
"\t}",
"\tvoid merge(int i,int j){",
"\t\ti=root(i);j=root(j);",
"\t\tif(i==j)return;",
"\t\tcou--;",
"\t\tif(rank[i]>=rank[j]){",
"\t\t\tparent[j]=i;",
"\t\t\t_size[i]+=_size[j];",
"\t\t}else{",
"\t\t\tparent[i]=j;",
"\t\t\t_size[j]+=_size[i];",
"\t\t}",
"\t\tif(rank[i]==rank[j])rank[i]++;",
"\t\treturn;",
"\t}",
"\tint count(){",
"\t\treturn cou;",
"\t}",
"\tint unitsize(int i){",
"\t\treturn _size[root(i)];",
"\t}",
"};",
],
},
ソースコード
c++で書いているし、サンプルもc++のコードをスニペット化したけど、どんな言語でもスニペットの書式に直せると思う。
ぜひ使ってみてね。
改善した方法とかがあれば、いろいろ教えてください。
インデントの幅はコード内のインデント変数を変えて調整してね。
//2020724 スニペット自動作成
# include<iostream>
# include<string>
# include<fstream>
using namespace std;
# define rep(i, n) for (int i = 0; i < (int)(n); i++)
int intend=4;
string ifname,ofname;
string body,name,prefix,scope;
int makeSnipett(ifstream &in,ofstream &out){
out << "\t\""+name+"\":{" << endl;
out << "\t\t\"scope\": \""+ scope + "\"," << endl;
out << "\t\t\"prefix\": \""+ prefix + "\"," << endl;
out << "\t\t\"body\": [" << endl;
while(getline(in,body)){
bool fixed=false;
int cou=0;
//空白文字の\tへの置き換え
for(cou;body[cou]==' ';cou++);
string a="";
rep(i,(cou+intend-1)/intend)a+="\\t";
body.replace(0,cou,a);
cou=a.size();
//その他の文字の置き換え
while(body[cou]!='\0'){
if(fixed){
fixed=false;
cou++;
continue;
}
char s=body[cou];
if(s=='\"'){
body.insert(cou,"\\");
fixed=true;
}else if(s=='\\'){
body.insert(cou,"\\");
fixed=true;
}
cou++;
}
body="\t\t\t\""+body+"\",";
//書き込み
out<<body<<endl;
}
out << "\t\t]," <<endl;
out << "\t}," <<endl;
return 0;
}
void Main(){
cout << "# where is code for snipett??" <<endl;
cin >> ifname;
ofname=ifname+"_snipett";
ifstream ifs(ifname);
ofstream ofs(ofname);
if(!ifs){
cerr<<"I failed to opne INPUT file"<<endl;
return;
}else if(!ofs){
cerr<<"I failed to opne OUTPUT file"<<endl;
return;
}else{
cout<<"success to open both files"<<endl;
}
//処理
string ans;
do{
cout << "# What is snipett name ?" <<endl;
cin >> name;
cout << "# What language is used in this ? Exmple:cpp,python,javascript,etc.." <<endl;
cin >> scope;
cout << "# What is prefix ? " <<endl;
cin >> prefix;
cout << "==============" <<endl;
cout << " name:"+name+"\n scope:"+scope+"\n prefix:"+prefix <<endl;
cout << "==============" <<endl;
cout << "# Is this OK ?? (Y/n)\n";
cin>>ans;
}while(ans[0]=='n'||ans[0]=='N');
cout << "making snipett ..." <<endl;
if(makeSnipett(ifs,ofs)==0)cout << "success!!" <<endl;
}
int main(int ARGV,char* ARGC[]){
Main();
}