字符串

字符串算法总结

1.字符流中第一个只出现一次的字符

package neu.yanyingnan.offer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
            /*题目描述
            请实现一个函数用来找出字符流中第一个只出现一次的字符。
            例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。
            当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
            输出描述:
            如果当前字符流没有存在出现一次的字符,返回#字符。*/
public class Solution_54 {
    Map<Character, Integer> map = new HashMap<Character, Integer>();//map是为了记录次数
    List<Character> list = new ArrayList<Character>();              //list是为了保证顺序  找第一个出现一次的
    //Insert one char from stringstream
    public void Insert(char ch){
        list.add(ch);//插入字符元素
        if(map.containsKey(ch))//利用map存放这些元素  并记录出现个数
            map.put(ch, map.get(ch)+1);
        else
            map.put(ch, 1);
    }

  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce(){
        for (Character ch : list) {//简单的遍历即可
            if(map.get(ch)==1)
                return ch;
        }
        return '#';
    }
}

2.判断字符串是否表示数值(包括整数和小数)

package neu.yanyingnan.offer;
            /*题目描述
            请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
            例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 
            但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。*/
public class Solution_53 {
    public static boolean isNumeric(char[] str) {//通过了  但是代码好不简洁
        if(str==null)
            return false;
        if(str.length==0)
            return false;
        if(!(str[0] == '+' || str[0] == '-' || (str[0]>='0'&&str[0]<='9')))
            return false;

        int dot = 0;//控制小数点只能有一个 
        int i;
        for(i=1; i<str.length && !(str[i]=='e'||str[i]=='E'); i++){//如果存在e就以它为分界点  两次for循环
            if(str[i] == '.'){
                dot++;
                if(dot>1)
                    return false;
            }
            if(!((str[i]>='0'&&str[i]<='9')||str[i]=='.'))
                return false;
        }

        if(i==str.length-1)//说明e在末尾  返回false
            return false;
        if(i==str.length-2 && (str[i+1]<='0'||str[i+1]>='9'))//说明e在倒数第二位  最后一位必须是0-9
            return false;
        if(i==1 && !(str[0]>='0'&&str[0]<='9'))//说明e在第二位  第一位如果不是0-9 返回false
            return false;
        if(i==str.length)//上面的for循环完成  不存在e 返回true
            return true;

        for(int j=i+1; j<str.length;j++){//e在中部
            if((str[j]=='+'||str[j]=='-')&&j==i+1)
                continue;
            if(!(str[j]>='0' && str[j]<='9'))
                return false;
        }
        return true;
    }

    public static void main(String[] args) {
        char[] str = {'5','e','2'};
        System.out.println(isNumeric(str));
    }
}

3.正则表达式匹配

package neu.yanyingnan.offer;
            /*题目描述
            请实现一个函数用来匹配包括'.'和'*'的正则表达式。
            模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。
             在本题中,匹配是指字符串的所有字符匹配整个模式。
             例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配*/

            /*当模式中的第二个字符不是“*”时: (思想用到了穷举和递归)
                    1、如果字符串第一个字符和模式中的第一个字符相匹配,  那么字符串和模式都后移一个字符,然后匹配剩余的。  
                    2、如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。 

                  而当模式中的第二个字符是“*”时: 
                    如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。 
                    如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式:  
                            1、模式后移2字符,相当于x*被忽略;  
                            2、字符串后移1字符,模式后移2字符;  
                            3、字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;  
                  这里需要注意的是:Java里,要时刻检验数组是否越界。*/
public class Solution_52 {
    public static boolean match(char[] str, char[] pattern) {  
        if (str == null || pattern == null) {  
            return false;  
        }  
        int strIndex = 0;  
        int patternIndex = 0;  
        return matchCore(str, strIndex, pattern, patternIndex);  
    }  

    public static boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) {  
        // 有效性检验:str到尾,pattern到尾,匹配成功  
        if (strIndex == str.length && patternIndex == pattern.length)  
            return true;  
        // pattern先到尾,匹配失败  
        if (strIndex != str.length && patternIndex == pattern.length)  
            return false;  
        // 模式第2个是*,且字符串第1个跟模式第1个匹配,分3种匹配模式;如不匹配,模式后移2位  
        if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {  
            if ((strIndex != str.length && pattern[patternIndex] == str[strIndex])  
                    || (pattern[patternIndex] == '.' && strIndex != str.length)) {  
                return // 模式后移2,视为x*匹配0个字符  
                matchCore(str, strIndex, pattern, patternIndex + 2)  
                        // 视为模式匹配1个字符  
                        || matchCore(str, strIndex + 1, pattern, patternIndex + 2)  
                        // *匹配1个,再匹配str中的下一个  
                        || matchCore(str, strIndex + 1, pattern, patternIndex);  

            } else {  
                return matchCore(str, strIndex, pattern, patternIndex + 2);  
            }  
        } // 模式第2个不是*,且字符串第1个跟模式第1个匹配,则都后移1位,否则直接返回false  
        if ((strIndex != str.length && pattern[patternIndex] == str[strIndex])  
                || (pattern[patternIndex] == '.' && strIndex != str.length)) {  
            return matchCore(str, strIndex + 1, pattern, patternIndex + 1);  
        }  
        return false;  
    }

    public static void main(String[] args) {
        char[] str = {0};
        char[] pattern = {'.'};
        System.out.println(match(str, pattern));
    }
}

4. 将一个字符串转换成一个整数

package neu.yanyingnan.offer;
            /*题目描述
                将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
                输入描述:
                输入一个字符串,包括数字字母符号,可以为空
                输出描述:
                如果是合法的数值表达则返回该数字,否则返回0
                示例1
                输入

                +2147483647
                    1a33
                输出

                2147483647
                    0
                */
public class Solution_49 {
    public int strToInt(String str){
        if(str==null || str.length()==0)//如果是空串返回零;
            return 0;

        if(str.equals("2147483647"))        //边缘值单独判断
            return 2147483647;
        else if(str.equals("-2147483648"))
            return -2147483648;


        int res = 0;
        char[] chs = str.toCharArray();
        int len = chs.length;

        for(int i=len-1,j=0; i>0; i--,j++){//从后向前计算 【48 57】之间为【0 9】
            if(chs[i]<48 || chs[i]>57)
                return 0;
            else
                res += (chs[i]-48)*Math.pow(10, j);
        }

        if(chs[0]>=48 && chs[0]<=57)        //第一个字符有可能为 +- 单独判断
            res += (chs[0]-48)*Math.pow(10, len-1);
        else if(chs[0]==45)
            res = -res;
        else if(chs[0] != 43)
            return 0;
        else
            return res;
        return res;
    }   
}

(完成)替换空格

            /*题目描述
            请实现一个函数,将一个字符串中的空格替换成“%20”。
            例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。*/
            //主要思路是从后往前覆盖。
public class Solution_02 {
    public String replaceSpace(StringBuffer str) {
        int count = 0;
        for(int i=0; i<str.length(); i++){
            if(str.charAt(i)==' ')
                count++;
        }
        int newLen = 2*count+str.length();
        int oldLen = str.length();
        str.setLength(newLen);
        for(int i=oldLen-1,j=newLen-1; i>=0;i--){
            if(str.charAt(i) == ' '){
                str.setCharAt(j--, '0');
                str.setCharAt(j--, '2');
                str.setCharAt(j--, '%');
            }else{
                str.setCharAt(j--, str.charAt(i));
            }
        }
        return str.toString();
        /*return str.toString().replace(" ", "%20");//然而一句话就搞定了   注意replace()方法 原字符串的值是不变的  改变的只是返回值 只能直接return
*/    }
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanyingnan1357/article/details/80337056
文章标签: 字符串算法
个人分类: 算法与数据结构
上一篇栈和队列
下一篇位运算
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭