【編碼】切割單詞流並逆向、大小寫反轉輸出-牛客聯合筆試程式設計題(一)-2016.04.08

peixn發表於2019-05-14

問題

給定一個只包含大小寫字母和空格的字串,線上性時間內對它做一些變形.把這個字串中由空格隔開的單詞反序,同時反轉每個字元的大小寫。比如”Hello World”,變形後成了”wORLD hELLO”。
輸入描述
給定一個字串以及他的長度n(1<=n<=500)。題目保證字串有大小寫字母和空格構成。
輸出描述
返回變形後的字串。
輸入例子
“This is a sample”,16
輸出例子
“SAMPLE A IS tHIS”

以下是我的原始碼:
OS:win10
IDE:visual studio 2010

第一種思路:用字串集合分別儲存單詞,然後合併。

string ReverseWords(string s, int n) {
        string *t=new string[100];
        string s1;
        int num=0;//the word cursor of s
        int i=0;//the char cursor of s

        //Cut s into words and put the words in the array t
        while(1){
            int j=0;//length of the word
            //Forward with the char cursor of s and cut when comes space
            //Get out a word of s 
            while(s.at(i)!=32){
                i++;
                j++;
                //stop when comes the end of s
                if(i>=n)
                    break;
            }
            //put the word of in t
            t[num].assign(s,i-j,j);
            num++;
            //stop when comes the end of s
            if(i>=n)
                break;
            i++;
        }

        int k=0;//the char cursor of s
        //traverse the words of s from right to left
        for(int i=0;i<num;i++){
            //put the word in s1
            for(int j=0;j<t[num-i-1].length();j++){
                s1.append(1,t[num-i-1].at(j));

                //Switch case
                if(s1.at(k)>64&&s1.at(k)<91){
                    s1.at(k)=s1.at(k)+32;
                }
                else if(s1.at(k)>96&&s1.at(k)<123){
                    s1.at(k)=s1.at(k)-32;
                }

               k++;
            }
            if(k<n){
                s1.append(1,` `);
                k++;
            }
            else
                break;
            
        }
        delete []t;
        return s1;
}

第二種思路:動態地將單詞插入目標字串頭部

string ReverseWords(string s, int n) {
        string s1;
        int num=0;//the word cursor of s
        int i=0;//the char cursor of s
        while(1){
            int j=0;//length of the word
            //Forward with the char cursor of s and cut when comes space
            //Get out a word of s 
            while(s.at(i)!=32){
                i++;
                j++;
                //stop when comes the end of s
                if(i>=n)
                    break;
            }
            string r;
            r.assign(s,i-j,j);//r is the word
            s1.insert(0,r);//insert r in the beginning of s1
            num++;
            if(i<n)
                s1.insert(0," ");
            else
                break;
            i++;
        }

        //Switch case
        for(int i=0;i<n;i++){ 
            if(int(s1.at(i))>64&&int(s1.at(i)<91)){
                s1.at(i)=s1.at(i)+32;
            }
            else if(s1.at(i)>96&&s1.at(i)<123){//不能寫成if
                s1.at(i)=s1.at(i)-32;
            }
        }

        return s1;
}

注意事項

1.string物件在未初始化前,不能按位置給相應的字元賦值。否則將訪問未知地址,導致程式意外停止。
2.string的介面功能強大,要靈活應用。比如方法二中用到的insert(),在方法一的基礎上大大簡化程式設計複雜度,使得程式碼更加簡潔。

其實所有C++中的STL介面不都是這樣嗎?如果恰當運用將事半功倍。

3.對於用new初始化的指標,千萬記得要加[],給定必要的空間大小。如string *t=new string[100];否則,t[1];就是訪問未知記憶體的錯誤!

`string *t=new string[100];`:申請一個指標t,指向一個字串陣列。
`string *t=new string;`:申請一個指標t,指向一個字串。

相關文章