读书笔记之《程序员代码面试指南(字符串问题)》

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

代码 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;

    }
}
posted @ 2018-01-30 20:23  daminzhou  阅读(248)  评论(0编辑  收藏  举报