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();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.isWhitespace(ch[i])){ i++; } int j=n-1;
while(j>-1&&Character.isWhitespace(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){ 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中的內容