zoukankan      html  css  js  c++  java
  • 读书笔记之《程序员代码面试指南(字符串问题)》

    字符串问题也是老生常谈的算法问题,该书罗列的字符串问题以我做算法的经验来看,都是很好的题。

    代码 Github 地址

    判断两个字符串是否互为变形词

    给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,那么str1和str2互为变形词。请实现函数判断两个字符串是否互为变形词。
    str1="123",str2="231",返回true。
    str1="123",str2="2331",返回false。

    先判断长度是不是一致

    再用一个长度为256的数组标记,一个加,一个减。最后看是不是互抵了。

    package String;
    /**
     * Created by zdmein on 2017/9/1.
     * 判断两个字符串是否互为变形词
     * 给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,
     * 那么str1和str2互为变形词。请实现函数判断两个字符串是否互为变形词。
       str1="123",str2="231",返回true。
       str1="123",str2="2331",返回false。
     */
    public class isDeformation1 {
        public static void main(String args []){
            String str1="54s6";
            String str2="465d";
            System.out.println(isDeformation(str1,str2));
        }
    
        public static boolean isDeformation(String str1 ,String str2){
            if(str1.length()!=str2.length()){
                return false;
            }
            int res[]=new int [256];
            int index=0;
            while (index!=str1.length()){
                res[str1.charAt(index)]++;
                res[str2.charAt(index++)]--;
            }
    
            for(int i=0;i<256;i++){
                if(res[i]!=0){
                    return false;
                }
            }
            return true;
        }
    }
    

    字符串的调整与替换

    *把 "a b c" 替换后为 “a%20b%20%20c”

    开辟空间,从尾部遍历替换到头部

    package String;
    
    /**
     * Created by zdmein on 2017/9/1.
     * 字符串的调整与替换
     *把 "a b  c" 替换后为  “a%20b%20%20c”
     */
    public class replace1 {
        public static void main(String [] args ){
            String str="a b  c";
            char chas[]=new char[20];
            for(int i=0;i<str.length();i++){
                chas[i]=str.charAt(i);
            }
            replace(chas);
    
        }
    
        public static void replace(char [] chas){
            int len=0;
            int num=0;
            for(;len<chas.length && chas[len]!=0;len++){
                if(chas[len]==' '){
                    num++;
                }
            }
            int index=len+num*2;
            for(;index>=0;index--){
                if (chas[len--]==' '){
                    chas[index--]='0';
                    chas[index--]='2';
                    chas[index]='%';
                }else {
                    chas[index]=chas[len+1];
                }
            }
            System.out.println(chas);
        }
    }
    

    扩展:

    只含有数字字符和“”字符的字符类型数组,把数字字符挪到右边, *挪到左边

    12**35

    **1235

    package String;
    
    /**
     * Created by zdmein on 2017/9/1.
     * 只含有数字字符和“”字符的字符类型数组,把数字字符挪到右边, *挪到左边
     12**35
     **1235
     */
    public class replace2 {
        public static void main(String [] args ){
            String str="12**35";
            char chas[]=new char[20];
            for(int i=0;i<str.length();i++){
                chas[i]=str.charAt(i);
            }
            modify(chas);
        }
    
        public static void modify(char [] chas){
            if(chas==null||chas.length==0){
                return;
            }
    
            int j=chas.length-1;
            for(int i=chas.length-1;i>=0;i--){
                if(chas[i]!='*'){
                    chas[j--]=chas[i];
                }
            }
    
            for(;j>=0;j--){
                chas[j]='*';
            }
    
            System.out.println(chas);
        }
    }
    

    翻转字符串

    写一个函数,将字符串翻转,翻转方式如下:“I am a student”反转成“student a am I”,不借助任何库函数。

    写个函数,先整体翻转一次,然后再每个单词翻转一次。easy!

    package String;
    
    /**
     * Created by zdmein on 2017/9/2.
     * 翻转字符串
     * 写一个函数,将字符串翻转,翻转方式如下:“I am a student”反转成“student a am I”,不借助任何库函数。
     */
    public class rotateWord1 {
        public static void main(String [] args){
            String str= "dogs love pig.";
    
            rotateWord(str);
        }
    
        public static void  rotateWord(String str){
            if(str==null||str.length()==0){
                return ;
            }
    
            char [] strArr = str.toCharArray();
            reverse(strArr,0,strArr.length-1);
            int index=0;
            for(int i=0;i<strArr.length;i++){
                if(strArr[i]==' '){
                    reverse(strArr,index,i-1);
                    index=i+1;
                }
            }
            reverse(strArr,index,strArr.length-1);
            System.out.println(strArr);
    
    
        }
    
        public static void reverse(char[] strArr ,int first ,int end){
            while (first<end){
                char tmp=strArr[first];
                strArr[first]=strArr[end];
                strArr[end]=tmp;
                first++;
                end--;
            }
        }
    }
    

    数组中两个字符串的最小距离

    • Assume that words = ["practice", "makes", "perfect", "coding", "makes"].

    • Given word1 = “coding”, word2 = “practice”, return 3.

    • Given word1 = "makes", word2 = "coding", return 1.

    用2个下标指向2个字符串,跟新位置,互相减,然后Math.min取小的。

    package String;
    
    /**
     * Created by zdmein on 2017/9/3.
     * 数组中两个字符串的最小距离
     *Assume that words = ["practice", "makes", "perfect", "coding", "makes"].
     *  Given word1 = “coding”, word2 = “practice”, return 3.
     *   Given word1 = "makes", word2 = "coding", return 1.
     */
    public class minDistance1 {
        public static void main(String args[]){
            String [] strs ={"1","3","3","3","2","3","1"};
            String str1="1";
            String str2="2";
            minDistance(strs,str1,str2);
    
        }
    
        public static void minDistance(String[] strs,String str1 , String str2){
            if(strs==null||strs.length==0||str1==null||str2==null){
                return;
            }
    
            int index1=-1;
            int index2=-1;
            int min=Integer.MAX_VALUE;
    
            for(int i=0;i<strs.length;i++){
                if(strs[i]==str1){
                    index1=i;
                    if(index2!=-1){
                        min=Math.min(min,index1-index2);
                    }
                }else if(strs[i]==str2){
                    index2=i;
                    if(index1!=-1){
                        min=Math.min(min,index2-index1);
                    }
                }
            }
          
          //
          if(min!=Integer.MAX_VALUE){
                System.out.println(min);
            }else {
                System.out.println(-1);
            }
          
          //上面这个渣渣代码可以这样写:
          // min==Integer.MAX_VALUE ? -1 : min;
        }
    }
    

    替换字符串中连续出现的指定字符串

    题目:
    给定单个字符串str、from和to,已知from字符串中无重复字符,把str中所有from的子串全部替换成to字符串,对连续出现from的部分要求只替换成一个to字符串,返回最终结果字符串。
    举例:
    str="123abc",from="abc",to="4567",返回"1234567";
    str="123",from="abc",to="4567",返回"123";
    str="123abcabc",from="abc",to="X",返回"123X";

    思路:

    把from匹配的字符,设为0,然后把0的部分全部替换掉成to,就好了

    package String;
    
    /**
     * Created by zdmein on 2017/9/4.
     * 替换字符串中连续出现的指定字符串
     题目:
     给定单个字符串str、from和to,已知from字符串中无重复字符,把str中所有from的子串全部替换成to字符串,对连续出现from的部分要求只替换成一个to字符串,返回最终结果字符串。
     举例:
     str="123abc",from="abc",to="4567",返回"1234567";
     str="123",from="abc",to="4567",返回"123";
     str="123abcabc",from="abc",to="X",返回"123X";
     */
    public class replace3 {
        public static void main(String args[]){
            String str="123abcabc";
            String from="abc";
            String to = "4567";
            System.out.println(replace(str,from,to));
    
        }
    
        private static String replace(String str,String from ,String to){
            if(str==null||from==""||to==""){
                return str;
            }
    
            char[] chstr=str.toCharArray();
            char[] chfrom=from.toCharArray();
            int match=0;
            for(int i=0;i<str.length();i++){
                if(chstr[i]==chfrom[match++]){
                    if(match==chfrom.length){
                        clear(chstr,i,chfrom.length);
                        match=0;
                    }
                }else {
                    match=0;
                }
            }
    
            String res="";
            for(int i=0;i<chstr.length;i++){
                if(chstr[i]!=0){
                    while (chstr[i]!=0){
                        res+=chstr[i++];
                    }
                }
    
                if(chstr[i]==0){
                    while (i!=chstr.length&&chstr[i]==0){
                        i++;
                    }
                    res+=to;
                    i--;
                }
    
            }
    
            return res;
        }
    
        private static void clear(char[] chstr , int end ,int len){
            while(len--!=0){
                chstr[end--]=0;
            }
        }
    }
    

    字符串的统计字符串

    统计字符串中每个字符的出现频率,返回一个字符串统计,key 为统计字符,value 为出现频率
    输入:
    aaabbadddffc
    输出:
    a_3_b_2_a_1_d_3_f_2_c_1

    先记录a,然后一项一项对比记录

    String.valueof()的使用

    package String;
    
    /**
     * Created by zdmein on 2017/9/5.
     * 字符串的统计字符串
     统计字符串中每个字符的出现频率,返回一个字符串统计,key 为统计字符,value 为出现频率
    输入:
     aaabbadddffc
     输出:
     a_3_b_2_a_1_d_3_f_2_c_1
    
     */
    public class getCountString1 {
        public static void main(String [] args){
            String str="aaabbadddffc";
            System.out.println(getCountString(str));
    
        }
    
        private static String getCountString(String str){
            if(str==null||str.length()==0){
                return "";
            }
    
            char [] chs=str.toCharArray();
            String res=String.valueOf(chs[0]);
            int num=1;
            for(int i=1;i<str.length();i++){
                if(chs[i]==chs[i-1]){
                    num++;
                }else {
                    res=res+"_"+String.valueOf(num)+"_"+String.valueOf(chs[i]) ;
                    num=1;
                }
            }
            return res+"_"+String.valueOf(num)+"" ;
        }
    }
    

    判断两个字符串是否互为旋转词

    题目:
    如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫做str的旋转词。
    如str="12345",str的旋转词有"12345"、"23451"、"34512"、"45123"、"51234"。
    给定两个字符串a和b,请判断a和b是否互为旋转词。
    举例:
    a="cdab",b="abcd",返回true;
    a="1ab2",b="ab12",返回false;
    a="2ab1",b="ab12",返回true。
    要求:
    如果a和b长度不一样,那么a和b必然不互为旋转词,可以直接返回false。
    当a和b长度一样,都为N时,要求解法的时间复杂度为O(N)。

    package String;
    
    /**
     * Created by zdmein on 2017/9/6.
     */
    public class isRotation {
    
        public boolean isRotation(String a ,String b){
            if(a==null||b==null||a.length()!=b.length()){
                return false;
            }
            String b2=b+b;
            return KMP(b2,a)!=-1;   //  KMP算法
        }
    
        public static int  KMP(String source , String pattern){
        //    int [] N=getN(pattern);
            return -1;
        }
    }
    

    判断是不是整体有效的括号字符串

    package String;
    
    import java.util.Scanner;
    
    /**
     * Created by zdmein on 2017/9/18.
     * 判断是不是整体有效的括号字符串
     * 括号字符串的有效性和最长有效长度
     */
    public class isValid1 {
        public static void main(String [] args){
            Scanner cin=new Scanner(System.in);
            String str=cin.next();
            System.out.println(isValid(str));
        }
    
        public static boolean isValid(String str){
            if(str==null ||str.equals("")){
                return false;
            }
    
            char [] chs=str.toCharArray();
            int status=0;
            for(int i=0;i<str.length();i++){
                if(chs[i]!=')'&&chs[i]!='('){
                    return false;
                }
                if(chs[i]==')'&&--status<0){
                    return false;
                }
                if(chs[i]=='('){
                    status++;
                }
            }
            return status==0;
    
        }
    }
    
    Learn ,Practice ,Summary !
  • 相关阅读:
    python使用pip离线安装库
    centos 6.5 ftp服务配置及客户端使用
    centos7 ntp服务器配置
    Python:如何排序(sort)
    python报OperationalError: (1366, "Incorrect string value..."的问题解决
    使用matplotlib画双纵轴坐标
    python安装PIL库
    【干货分享】前端面试知识点锦集04(Others篇)——附答案
    【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案
    【干货分享】前端面试知识点锦集02(CSS篇)——附答案
  • 原文地址:https://www.cnblogs.com/daminzhou/p/8387111.html
Copyright © 2011-2022 走看看