依照特定軌跡遍歷字符串圖
阿新 • • 發佈:2017-07-22
blog vector ddc comm urn convert 三層 print key
這裏面的x表示(如上圖)綠色的圓的補償,比方如以下4個綠色圓,
base=20/8=2
第一層=2+1=3;
第二層=2×2+1=5。
第三層=2×2+1=5;
第四層=2×2+1=5;
最後一層=2+0=2;
假設是以下這樣的情況
事實上算法也是一樣的僅僅要對於補償x值修正就能夠了。本次就不討論這樣的情況了。
實現函數例如以下
題目大致是這樣的,
字符串“PAYPALISHIRING”的一種“之”字型路線是這樣的:
假設一行一行的讀寫,就是PAHNAPLSIIGYIR。
所以,假設輸入PAHNAPLSIIGYIR和3,就是橫著的字符串和層數,輸出N軌跡的字符PAYPALISHIRING。
首先想到的是怎樣 將輸入字符串。切割開來,比方上面是3層,分成3個字符串,這三個字符串一定是連續的
第一段+第二段+第三段
如今的難題是怎麽推斷每一段的長度。
將上面的圖抽象化
就是這樣的,每個圓代表一個字符。這事實上是有規律的。
例如以下
這樣每一層的個數和這個周期之間是有關系的
base=(字符總個數/(層數+層數-2))
第一層個數=base+x
最後一層=base+x
其它層=base×2+x。
這裏面的x表示(如上圖)綠色的圓的補償,比方如以下4個綠色圓,
base=20/8=2
第一層=2+1=3;
第二層=2×2+1=5。
第三層=2×2+1=5;
第四層=2×2+1=5;
最後一層=2+0=2;
假設是以下這樣的情況
事實上算法也是一樣的僅僅要對於補償x值修正就能夠了。本次就不討論這樣的情況了。
到達這一步時,將之前的切割成了3部分,然後進行N軌跡遍歷,
初步方案是。給三個字符串編號1、2、3.然後依照12321232123的遍歷直到結束
所以如今須要解決的問題是,怎樣實現這樣的循環的遍歷。
這裏想到在cpu中有個寄存器用於決定地址是加一還是減一操作,所以借用這樣的思想。例如以下方案
實現函數例如以下
string convert(string text,int nRow)//text為輸入字符串 nRow是層數
{
string r;
vector <string> m;
int arry[251]={0};
int len=text.size();
int s,c;
s=len/(2*nRow-2); //base數據
c=len%(2*nRow-2); //為上面綠色的個數
for(int i=1;i<=nRow;++i)
{
if(i==1) //計算第一層的個數
{
if(c>=1)
arry[i]=s+1 ; //arry的下標表述層數,內容為當前層的個數
else
arry[i]=s;
}
else if(i==nRow) //計算最後一層的個數
{
if(c>=nRow)
arry[i]=s+1;
else
arry[i]=s;
}
else //中間層的個數
{
if(c>=i&&)
arry[i]=2*s+1;
else
arry[i]=2*s;
}
}
m.resize(nRow+1);
int loc;
int base;
base=0;
for(int i=1;i<=nRow;++i) //依據每一層的個數,切割字符串
{
base+=arry[i-1];
for(int j=0;j<arry[i];++j)
{
loc=j+base;
m[i].push_back(text[loc]);//m[i]保存每一層的字符串。
}
}
int flag=0; //~0 addr++ 0 add--
int cnt=1;
int* num=new int[nRow+1]();
//以下是在切割完畢後的循環遍歷
int x,y;
int tol=text.size();
while(1)
{
tol--;
if(tol<0)
break;
x=cnt;
y=num[cnt];
r.push_back(m[x][y]);
num[cnt]++;
if(cnt==nRow || cnt==1)
flag=~flag;
if(flag!=0)
cnt++;
else
cnt--;
}
cout<<r<<endl;
return r;
}
依照特定軌跡遍歷字符串圖