按照特定轨迹遍历字符串图

题目大致是这样的,

字符串“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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 09:07:23

按照特定轨迹遍历字符串图的相关文章

依照特定轨迹遍历字符串图

题目大致是这样的, 字符串"PAYPALISHIRING"的一种"之"字型路线是这样的: 假设一行一行的读写,就是PAHNAPLSIIGYIR. 所以,假设输入PAHNAPLSIIGYIR和3,就是横着的字符串和层数,输出N轨迹的字符PAYPALISHIRING. 首先想到的是怎样 将输入字符串.切割开来,比方上面是3层,分成3个字符串,这三个字符串一定是连续的 第一段+第二段+第三段 如今的难题是怎么推断每一段的长度. 将上面的图抽象化 就是这样的,每个圆代表一个

shell中遍历一句话,输出特定长的字符串

取出一系列字符串中特定长的字符串 方法一 #!/bin/bash hello="hello,world.my name is Jerry,what's your name ?" for word in ${hello[@]};do     [ ${#word} -gt 4 ] && echo $word done 方法二 [ `echo $word |wc -L` -gt 4 ] && echo $word 方法三  [ `expr length $wo

关于C#中遍历字符串中的每个字符的方法

解决方案 C#提供了两个方法用于遍历字符串. 1.第一个方法是foreach循环,这个方法快速且容易,但是与第二个方法相比它不太灵活.其使用方法如下: string testStr = "abc123"; foreach (char c in testStr) { Console.WriteLine(c.ToString()); } 2.第二个方法使用for循环而不是foreach循环来遍历字符串.例如: string testStr = "abc123"; for

Java 正确遍历字符串

Java字符串是一系列的Unicode字符序列,但是,它却常常被误认为是char序列.于是,我们经常这样来遍历字符串: package testchar; public class TestChar2 { public static void main(String[] args) { String s = "\u0041\u00DF\u6771\ud801\uDC00"; for(int i = 0; i < s.length(); i++) { System.out.prin

php遍历字符串每一个字符转换成数组。

php:遍历字符串每一个字符,追加给新数组. <?php /*    $str[$i]:字符串变量名+下标可以取值到对应下标的字符串的值.    explode(separator,string,limit)可以以固定字符为断点转换成数组    ru */ $str = "abcde";//被遍历的字符串 $arr = array();//定义要输出的数组 for($i=0;$i<strlen($str);$i++){//遍历字符串追加给数组 $arr[] = $str[$

for循环遍历字符串的还有一种方法

遍历字符c,让它各自等于字符串数组chars里面的各个字符.然后运行以下的语句,当c被赋值为chars里面全部字符各一次后.就会退出这个循环. 通常我们遍历字符串数组用 for(int i=0;i<array.length;i++){ array[i]; } 事实上使用for(String c:valueArray)更加方便 当中valueArray为字符串的数组,c为数组中的每一个字符串变量,直接訪问就可以 char[] cArray = num.toCharArray(); for (cha

for循环遍历字符串的另一种方法

遍历字符c,让它分别等于字符串数组chars里面的各个字符,然后执行下面的语句,当c被赋值为chars里面所有字符各一次后,就会退出这个循环. 通常我们遍历字符串数组用 for(int i=0;i<array.length;i++){ array[i]; } 其实使用for(String c:valueArray)更加方便 其中valueArray为字符串的数组,c为数组中的每个字符串变量,直接访问即可 char[] cArray = num.toCharArray(); for (char c

sql中遍历字符串

在sql或者存储过程中会需要遍历字符串. declare @idList varchar(500), --如111,222,333,尾部加, @str varchar(100), @Id int, @split varchar(10) set @split = ',' while(charindex(@split,@idList)<>0) begin set @str = substring(@idList,1,charindex(@split,@idList)-1) set @idList

UiPath:Split(&quot;,&quot;c)以逗号区分遍历字符串数组

学习中遇到同一用户多种职业的情况,因为所有的数据都是从Excel里面取的,所以只能把所有的职业写在一个单元格里,以逗号区分. 那么就需要先把字符串转为数组,然后遍历数组去添加职位.如图 Split(","c)截取字符串,然后遍历数组. 原文地址:https://www.cnblogs.com/youdao67/p/9968999.html