やっぱり、読んでて汚くて…
そこで、みなさんがソースを書くとき綺麗にするために気をつけてることがあれば教えてください!
それと、下にこの間作ったプログラムを載せるので、ダメだし等お願いします。
動きとしては、漢文に返り点をつけるプログラムで
漢文の文字数入力→漢文の読む順番を半角で区切って入力→上から順番につける返り点を表示
というものです。
今回は完成してから変数に意味を持たせるなど、気をつけて推敲してみました。(たぶんまだ駄目な気がしますが…)
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
using namespace std;
string moji[8][10]={{"上","中","下"},
{"一","二","三","四","五","六","七"},
{"上","下"},
{"甲","乙","丙","丁","戊","己","庚","辛","任","癸"},
{"天","地","人"},
{"元","亨","利","貞"},
{"春","夏","秋","冬"},
{"木","火","土","金","水"}
};
struct onetwo{
int revel;
int nest;
};
typedef vector<int> vec_i;
typedef vector<onetwo> vec_onetwo;
void solve(int n,vec_i read_order,vec_i num1,vec_i num2,vec_onetwo *edge);
void print_vector(vec_i vec);
void set_num1(vec_i *num1,vec_i num2,int n);
int main(){
vector<int> read_order;
vector<int> num1,num2; //num1は相対的な距離 num2はx回目に読む文字がy番目にあるのをnum2[x]=y
cout <<"漢文の文字数を入力"<<endl;
int n;
cin >>n;
num1.resize(n);
num2.resize(n);
onetwo start;
start.revel=-1;
start.nest=-1;
vector<onetwo> edge(n,start);
cout << "漢文の読む順番を半角スペースで区切って入力"<<endl;
for(int i=0;i<n;i++){
int a;
cin >> a;
read_order.push_back(a-1);
num2[a-1]=i;
}
set_num1(&num1,num2,n);
solve(n,read_order,num1,num2,&edge);
for(int i=0;i<n;i++){
if(i!=n&&num1[i+1]==-1) //次に進む場所が一つ前なら
cout <<"レ"; //レ点
else
cout <<" ";
if(edge[i].nest!=-1){ //nestが初期値と違ったら
cout<<moji[edge[i].nest][edge[i].revel]; //一二点系返り点表示
if(num1[i]==1) //一二点の後、行き先が一つ下なら
cout <<"|"; //ハイフン表示
else
cout <<" ";
}else{
cout <<" ";
}
cout<<":"<<endl;
}
return 0;
}
void solve(int n,vec_i read_order,vec_i num1,vec_i num2,vec_onetwo *edge){
int revel=0;
int nest=1;
vector<int>check_same_nest;
for(int i=0;i<n;i++){
if(num1[ num2[i] ]<-1){ //2個以上もどるとき ex: 一,上
onetwo now;
now.revel=revel; //revel引き継ぎ
for(int now=num2[i]-1 ; now>num2[i+1] ; now--){ //返り点の間に別の返り点があるかチェック
if((*edge)[now].nest>=nest){ //自分以上にnestの高いのがいれば
nest = (*edge)[now].nest + 1; //それ+1を代入
}
}
check_same_nest.push_back(num2[i]); //通った点を記録
if((*edge)[ check_same_nest[0] ].nest<nest){ //昔のネストが今より低かった時
for(int i=0 ; i<check_same_nest.size() ; i++){
(*edge)[ check_same_nest[i] ].nest=nest; //過去の地点に今のネストを代入
}
}
if(nest==2){ //上下点の処理
switch(revel){
case 1: //上中下点へ
nest=0;
break;
case 2: //甲乙点へ
nest=3;
for(int i=0;i<2;i++){
(*edge)[ check_same_nest[i] ].nest=3;
}
break;
}
}
now.nest=nest; //ネストを代入
(*edge)[ num2[i] ]=now; //答えに代入
revel++;
now.revel=revel; //返る場所にも返り点をつける ex:二,下
(*edge)[ num2[i+1] ]=now;
}else{ //返り点が連続しなかったとき
check_same_nest.clear(); //データをそれぞれ初期化
revel=0;
nest=1;
}
}
}
void set_num1(vec_i *num1,vec_i num2,int n){
for(int i=0;i<n-1;i++){
(*num1)[ num2[i] ]=num2[i+1]-num2[i];//相対距離を代入
}
(*num1)[ num2[n-1] ]=0;//終点には0を代入
}
void print_vector(vec_i vec){//与えられた配列の全要素を表示
for(int i=0;i<vec.size();i++)cout <<setw(2)<<internal<< vec[i]<<endl;
cout <<endl;
}
}