• Leetcode_06_ZigZag Conversion (easy)


    ZigZag Conversion------(String)

    题目:

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

    P   A   H   N
    A P L S I I G
    Y   I   R
    

    And then read line by line: "PAHNAPLSIIGYIR"

    Write the code that will take a string and make this conversion given a number of rows:

    string convert(string text, int nRows);

    convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

    解答:

    首先将string字符串转化为char数组

    有几种方法。

    1. 使用string类的c_str()函数strcpy(str,string.c_str());

      strcpy原型声明:char *strcpy(char* dest, const char *src);
      头文件:#include <string.h> 和 #include <stdio.h>
      功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 
      c_str()语法: 
      const char *c_str();
      c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.
      这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
      注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针
      比如:最好不要这样:
      char* c;
      string s="1234";
      c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理

      应该这样用:
      char c[20];
      string s="1234";
      strcpy(c,s.c_str());
      这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作
    2. for循环实现

      for(i =0 ;i < string.size();i++)

              str[i] = string.at(i);

    3. 使用string类的copy函数

      string.copy(str,0,string.size());

    规律:

             第一行两个元素相差为numRow*2-2,相差空格为numRow-2

             第i行相差

                  往下:( numRow-(i-1))*2-2,相差空格为numRow-(i-1)-2

                  往上:i*2-2,相差空格为i-2

            判断往上还是往下:

                 num/(numRow*2-2)与(numRow*2-2)/2比较大小

                 大:往上   小:往下

           除第一行和最后一行外,都是先下再上循环

    //自己写的程序,新手渣渣一枚

    #include <iostream>

    using namespace std;

    class Solution {

    public:

        string convert(string s, int numRows) {

            if(s.length()==0||numRows<1)return s;

            char str[30];

            string final;

            strcpy(str,s.c_str());

            for(int i=0;i<numRows;i++){

                int flag=1;

                int keyboardNum = 0;

    //            if(i==numRows-1){//除了最后一个,其他一开始都是往下

    //                keyboardNum = i-1;

    //            }else{

    //                keyboardNum=numRows-i-2;

    //            }

                for(int j=i;j<=sizeof(s);){

                    for(int a=0;a<keyboardNum;a++){

    //                    printf(" ");//每次打印一个数和后面的空格

                        final+=" ";

                    }

                    final+=str[j];

                    if(flag&&i!=numRows-1){//除了第一行和最后一行,其他都是先往下在往上循环

                        j=j+(numRows-i)*2-2;

                        keyboardNum=numRows-i-2;

                        if(i!=0){

                          flag = 0;

                        }

                    }else{

                        j=j+(i+1)*2-2;

                        flag = 1;

                        keyboardNum = i-1;

                    }

                   

                }

    //            printf(" ");

                final+=" ";

            }

          

            return final;

        }

    };

    int main(int argc, const char * argv[]) {

        

        Solution a;

        cout<<a.convert("ABCDEFGHIJKIJIIONINOON", 5)<<endl;

        return 0;

    }

     结果超时了,晕。

    仔细一看原来不用输出z字型格式,只要求字母顺序对即可,同学们,一定要认真审题啊>_<

    修改过后:

    class Solution {

    public:

        string convert(string s, int numRows) {

            if(s.length()==0||numRows<1)return s;

            string final="";

            for(int i=0;i<numRows;i++){

                int flag=1;

                for(int j=i;j<s.length();){

                 

                    final+=s.at(j);

                    if(flag&&i!=numRows-1){//除了第一行和最后一行,其他都是先往下在往上循环

                        j=j+(numRows-i)*2-2;

                        if(i!=0){

                            flag = 0;

                        }

                    }else{

                        j=j+(i+1)*2-2;

                        flag = 1;

                    }

                    

                }

            }

            

            

            return final;

            

        }

    };

    //依然超时,晕

    看了网上的代码

    class Solution {

        public: string convert(string s, int nRows) {

            unsigned long len = s.length();

            if (len == 0 || nRows < 2) return s;

            

            string ret = "";

            int lag = 2*nRows - 2; //循环周期

            for (int i = 0; i < nRows; i++) {

                for (int j = i; j < len; j += lag) {

                    ret += s.at(j);

                    

                    //非首行和末行时还要加一个

                    if (i > 0 && i < nRows-1) {

                        int t = j + lag - 2*i;

                        if (t < len) {

                            ret += s.at(t);

                        }

                    }

                }

            }

            return ret;

        }

    };

    发现所有行的重复周期都是 2 * nRows - 2

    对于首行和末行之间的行,还会额外重复一次,重复的这一次距离本周期起始字符的距离是 2 * nRows - 2 - 2 * i

     
  • 相关阅读:
    Android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析
    软件的三层架构
    【Android小应用】颈椎保健操Android开源项目
    huffman编码——原理与实现
    30天自制操作系统之第13天 定时器(2)
    JSP中Session的使用
    [非官方]ArcGIS10.2 for Desktop扩展工具包——XTools Pro
    在C语言中,double、long、unsigned、int、char类型数据所占字节数
    nyoj 130 同样的雪花 【哈希】
    socketpair的使用
  • 原文地址:https://www.cnblogs.com/ganeveryday/p/4887120.html
Copyright © 2020-2023  润新知