1. 程式人生 > >華為筆試算法題1

華為筆試算法題1

通過 print 兩指針 結構 == 輸出結果 com 英文 在一起

三道題目基本上都和字符串操作相關。

1. 給定一組元素個數不定的字符串數組,每個字符串的長度不定;請統計出該字符串數組中的英文字母子串、數字子串和其他字符子串的總數; 輸出為以","符號分隔3個數值,分別代表英文字母子串、數字子串和其他字符子串的數量; 實現時無需考慮非法輸入。

輸入描述:
輸入為:
字符串數組

例子:abcd1244!! BKMKLK0987%

輸出描述:
輸出為以","符號分隔3個數值,分別代表英文字母子串、數字子串和其他字符子串的數量。

輸入例子:
abcd1244!! BKMKLK0987%

輸出例子:
2,2,2

思路:從左往右掃描輸入字符串,利用兩指針指向字符串的開始兩個字符,往後遞增,每一個步判斷兩指針所指的字符是否相同,如果不相同,則將後一個指針所指的字符類型所對應的字符字串計數器加1.

代碼:

#include<iostream>
#include<string>

using namespace std;

bool isSameType(char *p1,char *p2);

int main()
{
    string str;
    cin>>str;
    int alpha=0;
    int digi=0;
    int rest=0;
    int n=str.size();
    if(n==0){
        return 0;
    }else if(n==1){
        if((str[0]>=
a&&str[0]<=z)||(str[0]>=A&&str[0]<=Z)){ cout<<"1,0,0"<<endl; }else if(str[0]>=0&&str[0]<=9){ cout<<"0,1,0"<<endl; }else{ cout<<"0,0,1"<<endl; } return 0; }
/*初始前一個指針從空開始,第二指針指向字符串中的第一位,從左向右遍歷,每次兩個指針所指 向的字符類型不同時,判斷第二個指針所指字符的類型,將相應的計數器加1*/ char *p1=NULL; char *p2=&str[0]; for(int i=0;i<n-1;){ if(!isSameType(p1,p2)){ if((*p2>=a&&*p2<=z)||(*p2>=A&&*p2<=Z)){ alpha++; }else if(*p2>=0&&*p2<=9){ digi++; }else{ rest++; } } i++; p1=&str[i]; p2=&str[i+1]; } cout<<alpha<<","<<digi<<","<<rest<<endl; return 0; } bool isSameType(char *p1,char *p2) { int type1; int type2; if(p1==NULL){ return false; } if((*p1>=a&&*p1<=z)||(*p1>=A&&*p1<=Z)){ type1=0; }else if(*p1>=0&&*p1<=9){ type1=1; }else{ type1=2; } if((*p2>=a&&*p2<=z)||(*p2>=A&&*p2<=Z)){ type2=0; }else if(*p2>=0&&*p2<=9){ type2=1; }else{ type2=2; } if(type1==type2){ return true; }else{ return false; } }

2. 輸入一個字符串,對其進行逐詞的反轉後,然後返回。 比如:

輸入:"the sky is blue"
輸出:"blue is sky the"
註意: 1)“詞”是指:任何不含空格的連續字符串
    2)輸入字符串可以有首尾空格,但是返回的字符串不能有首尾空格
    3)輸入字符串中兩個詞之間可以有多個空格,但是返回的字符串中詞只能用單個空格隔開

思路:利用棧的先進後出特性,從右往左倒序讀取數組,如果是字母則入棧,遇到空格時將棧中所有字母彈出並輸出,再輸出一個空格,這裏註意的是考慮到原字符串裏可能有多個空格連在一起的情況,所以遇到空格出棧中字母之前需要判斷此時棧是否為空。當然了,對原字符穿一開始還要去掉首位空格才行。

代碼:

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String ss=sc.nextLine();
        ArrayList<Character>  chr=new ArrayList<>();
        char[] ch=ss.toCharArray();
        int n=ch.length;
        Stack stack=new Stack();
        if(n==0){
            return;
        }
        /*去首尾空格*/
        int i=0;
        /*這裏要加上判斷條件i<n,否則如果輸入的全是空格的話數組會越界*/
        while(i<n&&Character.isSpace(ch[i])){
            i++;
        }
        int j=n-1;
        /*同上*/
        while(j>-1&&Character.isSpace(ch[j])){
            j--;
        }
        
        while(j>=i){
            /*如果判斷到原字符串的第一個單詞,此時將棧中字母彈出即可,不需要輸出空格*/
            if(j==i){
                /*這裏要記得把第一個字符壓入棧*/
                stack.push(ch[j]);
                int size=stack.size();
                for(int k=0; k<size; k++){
                    System.out.print(stack.pop());
                }
            }else if(Character.isSpace(ch[j])){
                /*如果是空格,並且棧不是空,則彈出棧中所有字母,並輸出一個空格。
                  這裏的棧是否為空判斷是為了避免輸出可能的多余空格*/
                if(stack.size()!=0){
                    int size=stack.size();
                    for(int k=0; k<size; k++){
                        System.out.print(stack.pop());
                    }
                    System.out.print(" ");
                }
            }else{
                /*是字母的話直接入棧即可*/
                stack.push(ch[j]);
            }
            j--;
        }
    }
}

3. LISP語言唯一的語法就是括號要配對。形如 (OP P1 P2 ...),括號內元素由單個空格分割。其中第一個元素OP為操作符,後續元素均為其參數,參數個數取決於操作符類型

註意:參數 P1, P2 也有可能是另外一個嵌套的 (OP P1 P2 ...),當前OP類型為 quote / reverse / search / combine 字符串相關的操作:

- quote: 引用一個字符串,即返回字符串本身內容,參數個數 1

- reverse: 把字符串反轉,並返回,參數個數 1

- search: 在第一個字符串中查找第二個字符串的第一次出現,返回從這開始到結束的所有字符串,如果查找不到,返回空字符串,參數個數 2

- combine: 把所有字符串組合起來,參數個數不定,但至少 1 個

其中P1, P2 等參數可能是帶雙引號的字符串,如 "abc",也有可能是另外一個 (OP P1 P2 ...),上述字符串包括引號;引號中間的所有字符,均為 ASCII 可打印字符,且不會再出現引號 ("),輸出也為帶雙引號的字符串

舉例:
輸入字符串 輸出結果
(quote "!@#$%") "!@#$%"
(reverse "a b c") "c b a"
(search "abcdef" "cd" ) "cdef"
(search "abcdef" "xy" ) ""
(combine "a" "b" "cde) ") "abcde) "
(search (combine "1234567890" "abcdefgh" "1234567890") (reverse "dc")) cdefgh1234567890

輸入描述:
合法C字符串,字符串長度不超過512;用例保證了無語法錯誤.

輸出描述:
合法C字符串,需要帶括號

輸入例子:
(search "huawei" "we")

輸出例子:
"wei"

思路:利用棧結構,遇到 "(" 、操作符、操作數都壓入棧,遇到")" 持續出棧 直至彈出一個 "(", 計算結果,再將這個結果壓入棧。

代碼:

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String ss=sc.nextLine();
        Stack<String> stack=new Stack<String>();
        StringBuilder temp1=new StringBuilder();  //字符串緩存,用來判斷累積讀入的字符是否構成一個操作數/操作符
        List<String> temp2=new ArrayList<String>(); //用於存儲棧彈出來的操作數
        char[] chars=ss.toCharArray();
        int n=chars.length;
        /*從左往右掃描字符數組*/
        for(int i=0;i<n;i++){
            /*如果是 ( ,要判斷是否實在操作數中,是的話加入緩存字符串,不是的話直接入棧*/
            if(chars[i]==‘(‘){
                if(temp1.indexOf("\"")==-1){
                    stack.push("(");
                }else{
                    temp1.append(‘(‘);
                }
            }
            /*如果是 ) ,要判斷是否實在操作數中,是的話加入緩存字符串,不是的話出棧至遇到一個 ( */
            else if(chars[i]==‘)‘){
                /*根據緩存字符串中有沒有 " 來判斷是否在一個操作數中*/
                if(temp1.indexOf("\"")!=-1){
                    temp1.append(‘)‘);
                }else{
                    String back=stack.pop();
                    while(!back.equals("(")){
                        temp2.add(back);
                        back=stack.pop();
                    }
                    String operator=temp2.get(temp2.size()-1);
                    switch(operator){
                        case "quote":
                            stack.push("\""+(temp2.get(0)).replaceAll("\"","")+"\"");
                        break;
                        case "search":
                            stack.push(search(temp2.get(1),temp2.get(0)));
                        break;
                        case "reverse":
                            stack.push(reverse(temp2.get(0)));
                        break;
                        case "combine":
                            String stringComb=combine(temp2.subList(0,temp2.size()-1));
                            stack.push(stringComb);
                        break;
                    }
                    temp2.clear();
                }
            }
            /*如果是空格,判斷空格是否在操作數字符串中,不是的話原先的字符串緩存已經構成一個操作數/符,壓入棧。
              是的話加入到字符串緩存中*/
            else if(chars[i]==‘ ‘){
                if((temp1.indexOf("\"")!=-1)&&(chars[i-1]!=‘\"‘)){
                    temp1.append(chars[i]);                
                }else{
                    if(temp1.length()>0){
                        String tempString=temp1.toString();
                        stack.push(tempString);
                        temp1.setLength(0);
                    }
                }
            }
            /*如果遇到成對的 " ,表明緩存的是一個操作符/數,將其壓入棧*/
            else if((chars[i]==‘\"‘)&&(temp1.indexOf("\"")!=-1)){
                if(temp1.length()>0){
                        temp1.append(‘\"‘);
                        String tempString=temp1.toString();
                        stack.push(tempString);
                        temp1.setLength(0);
                    }
            }
            /*字母或者數字的情況直接加入到字符串緩存*/
            else{
                temp1.append(chars[i]);
            }
        }
        for(int i=0;i<stack.size();i++){
            System.out.print(stack.pop());
        }
    }
    
    static String search(String s1,String s2){
        s1=s1.replaceAll("\"","");
        s2=s2.replaceAll("\"","");
        if(s1.indexOf(s2)!=-1){
            return "\""+s1.substring(s1.indexOf(s2))+"\"";
        }else{
            return  "\""+ "\"";
        }
    }
    
    static String reverse(String s){
        s=s.replaceAll("\"","");
        StringBuilder sb=new StringBuilder();
        char[] chars=s.toCharArray();
        for(int i=chars.length-1;i>=0;i--){
            sb.append(chars[i]);
        }
        return "\""+sb.toString()+"\"";
    }
    
    static String combine(List<String> l){
        StringBuilder sb=new StringBuilder();
        for(int i=l.size()-1;i>=0;i--){
            String s=(l.get(i)).replaceAll("\"","");
            sb.append(s);
        }
        return "\""+sb.toString()+"\"";
    }
}

註:

判斷StringBuilder是否為空:temp1.length()>0,通過長度是否大於0來判斷,以及利用setLength(0)來清空StringBuilder中的內容

華為筆試算法題1