文字列処理は難しい。

photo by Jen Son
提出しました。今日のSRMはネットの設定に手間取り出場できませんでした。残念。仕方がないので過去問をときました。
TopCoder Statistics - Problem Statement
小文字のアルファベットを使って暗号を作ります。まずアルファベットabcd…をfSとfS+1番目を境にふたつのグループにわけます。順番が若いグループはアルファベットをfR個先のものへ変更します。グループの端まできたら先頭に回ります。もう一方もsR個向こうのものへ同様に変更します。空白はそのまま。
例: fS=3,fR=1,sR=0 mes="abcd xyz"
答え:"bcad xyz"
例: fS=3,fR=1,sR=1 mes="abcd xyz"
答え:"bcae yzd"
文字コードを使う方法が分からなかったのであらかじめアルファベット順にabcd…という文字列をつくっておいて、それと比較して数字に変更します。ちなみ空白は27番目です。
- string型は変数名.size()で文字の長さを取得できます。
- また、変数名.push_back(文字)で、後ろから”文字”を接続します。
- 変数名.substr(i,n)で変数名のi番目文字(0から始まる)からn個の文字列を抽出します。
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
class TwoRotationCypher {
public:
string encrypt(int fS, int fR, int sR, string mes){
string alb( "abcdefghijklmnopqrstuvwxyz " );
string mes2,mes3;
int i=0,leng=mes.size();
unsigned int k,nk=0;
printf("fS=%d fR=%d sR=%d\n",fS,fR,sR);
for(i=0;i<leng;i++){
mes2=mes.substr(i,1);
if(mes2==" "){
k=0;nk=1;
mes3.push_back(alb[26]);
}else{
k=alb.find( mes2,0)+1;
if(k <= fS){
nk=(k+fR)%fS;
if(nk ==0){nk=fS;}
}else{
nk=(k-fS+sR)%(26-fS)+fS;
if(k+sR == 26){nk=26;}
}
mes3.push_back(alb[nk-1]);
}
//cout << mes2 << "---" << k <<"---"<< nk << mes3 <<endl;
}
cout << mes3 <<endl;
return mes3;
}
};
int main(){
TwoRotationCypher ob1;
int fS,fR,sR;
string mes;
printf("input1:");
scanf("%d%d%d",&fS,&fR,&sR);
printf("\n");
mes ="hello world";
printf("%s\n",mes.c_str());
ob1.encrypt(fS,fR,sR,mes);
return 0;
}
以上。他の人のコードも観てこよう。
-
-
-
- -
-
-
追記:20130208
文字コードは'a'などであらわせる模様。
int (mes[i]-'a')でアルファベットのインデックスが取り出せる。
string型のmesのi番目の文字がbならint (mes[i]-'a')=1
文字に直すときはchar(int型))。