• 笔试算法题记录2


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

  • 相关阅读:
    Asp.net中导出Excel文档(Gridview)
    以太坊难度炸弹是什么?极大抑制矿工继续以POW方式挖矿!
    Solidity语言基础 和 Etherum ERC20合约基础
    BCH/BSV coin split troubleshooting
    比特币学习-Transaction的locktime属性
    在BCH硬分叉后防止重放攻击-2
    在BCH硬分叉后防止重放攻击-1
    区块链硬分叉-软分叉简单了解
    BTC和BCH 区别和联系?
    BCHABC/BCHSV的矛盾所在
  • 原文地址:https://www.cnblogs.com/f91og/p/7093363.html
Copyright © 2020-2023  润新知