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中的内容

posted on 2017-06-30 19:02  f91og  阅读(1405)  评论(3编辑  收藏