服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言详解Z字形变换排列的实现

C语言详解Z字形变换排列的实现

2022-11-16 15:35Fengliguantou@ C/C++

Z字形变换排列就是指将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列,下面让我们用C语言来实现

题目链接:Z 字形变换

C语言详解Z字形变换排列的实现

方法一

——找规律模拟数组

题目要求构造一个从左到右的Z型矩阵。

通过分析,可以看出这个Z型矩阵的特点

C语言详解Z字形变换排列的实现

Z型矩阵就是如图中的橙色,绿色这样部分组合在一起的,Z型矩阵就是由一个个这样相同周期组成的。

这里有一种情况需要特殊讨论,当矩阵只有一行时,直接返回原字符。

其余情况均可满足。

其周期的构成满足这样一个规律:

在第一列向下填写矩阵行数r个字符,接着向其右上部分共(r-2)列分别填写一个字符。Z型矩阵的周期t=r+r-2=2*r-2,每个周期会占用矩阵的r-1列,总共有 字符长度len/t个周期(将最后一个周期视作完整周期)。

因此创建一个具有r行c列的的二维矩阵,(这里在计算列的时候需要多+一个周期,因为除法的计算会舍去余数)。一开始从(0,0)这个位置开始填写字符,通过判断i%t与r-1的大小决定向上移动还是向下移动。

共两种情况:

i%t<r-1 :说明这时矩阵正在填写第一列的数字,这时只需要向下移动

i%t>=r-1:说明第一列已经填写好了,这时需要向右上方进行填写字符,所以需要向右移动一位,向上移动一位。

当一个周期运行完时,又会回到新周期的第一列。

再次遍历矩阵,将存储有字符的位置加入到一个新的字符串中。

class Solution {
public:
  string convert(string s, int numRows) {
      if(numRows==1||numRows>=s.size())//特殊情况进行排除
      return s;
    int r=numRows;//矩阵的行数
    int t=2*r-2;//周期所含字符个数
    int len=s.size();//字符串的长度
    int c=(len+t)/t*(r-1);//二维矩阵列数
    vector<string> v1 (r,string(c,0));
  for(int i=0, x=0,y=0;i<len;i++){
      v1[x][y]=s[i];
      
      if(i%t<r-1){
          x++;//向下移动
      }
      else{
          x--;//向上移动
          y++;//向右移动
      }  
  }
  string ans;
  for(int i=0;i<r;i++){//遍历矩阵,扫描字符并添加
      for(int j=0;j<c;j++){
          if(v1[i][j])
          ans+=v1[i][j];
      }
  }
  return ans;
  }
};

时间复杂度=o(nr)

空间复杂度=o(nr)

 

方法二

——压缩矩阵

在第一种方法,需要构造一个二维矩阵,但是其实只使用了其中的部分空间,这样就导致浪费了许多空间,因此可以对矩阵进行压缩。

依旧是将矩阵只有一行的情况进行额外讨论,若成立,直接返回原字符串。 反之,创建一个r行1列的的string数组,通过判断字符i的位置(与第一种方法的判断方式一样),直接将字符填写到数组的对应行。 举例说明:

C语言详解Z字形变换排列的实现

这个Z型字符在模拟数组是这样呈现的:

C语言详解Z字形变换排列的实现

class Solution {
public:
  string convert(string s, int numRows) {
  int len=s.size();//字符串长度
  int r=numRows;//矩阵行数
  int t=2*r-2;//周期所含字符个数
   if (r == 1) {
          return s;
      }
  vector<string> v1(r);
  int x=0;
      for(int i=0;i<len;i++){
          v1[x]+=s[i];
          if(i%t<r-1)
          x++;//向下移动
          else
          x--;//向上移动
      }
      string ans;
      for (auto &row : v1) {//遍历矩阵,扫描字符并添加
          ans += row;
      }
  return ans;
  }
};

时间复杂度:o(n)

空间复杂度:o(n)

到此这篇关于C语言详解Z字形变换排列的实现的文章就介绍到这了,更多相关C语言Z字形变换内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_59112191/article/details/123238696

延伸 · 阅读

精彩推荐
  • C/C++VC中Tab control控件的用法详细解析

    VC中Tab control控件的用法详细解析

    以下是对VC中Tab control控件的用法进行了详细的介绍,需要的朋友可以过来参考下哦...

    C语言教程网7162020-12-28
  • C/C++C语言中的初阶指针详解

    C语言中的初阶指针详解

    这篇文章主要介绍了C语言中的初阶指针,介绍了其相关概念,具有一定参考价值。需要的朋友可以了解下,希望能够给你带来帮助...

    地火轰雷7032022-01-19
  • C/C++C++ 操作系统内存分配算法的实现详解

    C++ 操作系统内存分配算法的实现详解

    本文主要介绍了在动态分区管理方式下采用不同的分配算法实现主存分配和实现主存回收,旨在帮助学生理解在动态分区管理方式下应怎样实现主存空间的...

    Carmelo_77902022-02-25
  • C/C++C语言实现出栈序列

    C语言实现出栈序列

    这篇文章主要为大家详细介绍了C语言实现出栈序列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    奋斗的龙猫5062021-11-03
  • C/C++C语言扫雷游戏的实现代码

    C语言扫雷游戏的实现代码

    这篇文章主要为大家详细介绍了C语言扫雷游戏实现代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Monster_ii4192021-08-25
  • C/C++c++中容器之总结篇

    c++中容器之总结篇

    本文总结了C++的容器,其大致可以分为两个大类:顺序容器和关联容器,需要了解的朋友可以参考下...

    panmaoge6502021-03-04
  • C/C++在C++程序中开启和禁用Windows设备的无线网卡的方法

    在C++程序中开启和禁用Windows设备的无线网卡的方法

    这篇文章主要介绍了在C++程序中开启和禁用Windows设备的无线网卡的方法,包括一些常见错误的分析与解决,需要的朋友可以参考下...

    全速前行10612021-03-29
  • C/C++C语言单循环链表的表示与实现实例详解

    C语言单循环链表的表示与实现实例详解

    这篇文章主要介绍了C语言单循环链表的表示与实现,对于学习数据结构与算法的朋友来说很有参考借鉴价值,需要的朋友可以参考下...

    C语言程序设计8492021-01-21