算法与数据结构-字符串 讲解与java代码实现
2018-02-01 11:10
866 查看
1.基础
2.例题
1. 拓扑结构相同子树练习题
KMP算法及示例讲解:http://blog.csdn.net/bury_/article/details/79199228
import java.util.*; //拓扑结构相同的子树判断,要求时间复杂度为O(n) /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }*/ public class IdenticalTree { public boolean chkIdentical(TreeNode A, TreeNode B) { //采用先序遍历的方法遍历并序列化树,有值则打印val!,空值则打印#! String Astr=serilizeTree(A); String Bstr=serilizeTree(B); int len=Astr.length(); int lenP=Bstr.length(); char[] Aarray=Astr.toCharArray(); char[] Barray=Bstr.toCharArray(); //KMP算法计算序列化后的A是否包含B //遍历长度为m的字符串,时间复杂度O(m) return KMP(Aarray,Barray); } //str是待检测字符串,ptr是搜索的模式子串 public boolean KMP(char[] str,char[] ptr){ //计算模式子串的next数组 int[] next=cal_next(ptr); int slen=str.length; int plen=ptr.length;//子串的长度 int k 11145 =-1; for(int i=0;i<slen;i++){ while(k>-1&&ptr[k+1]!=str[i]){ k=next[k]; } if(ptr[k+1]==str[i]){ k=k+1; } if(k==(plen-1)){ //return i-lenp+1; return true; } } return false; } public String serilizeTree(TreeNode A){ Stack<TreeNode> stack=new Stack<TreeNode>(); stack.push(A); String result=new String(); TreeNode cur; while(!stack.isEmpty()){ cur=stack.pop(); if(cur==null){ result+="#!"; }else{ result+=cur.val+"!"; stack.push(cur.right); stack.push(cur.left); } } return result; } public int[] cal_next(char[] s){ int len=s.length; int[] next=new int[len]; next[0]=-1; int k=-1;//k表示s[0,k]字符串的最长前缀等于最长后缀时的最长前缀长度减去1 //遍历长度为n的子串,时间复杂度O(n) for(int q=1;q<=(len-1);q++){ //如果下一个不同,那么k就变成next[k],注意next[k]是小于k的,无论k取任何值。 while(k>-1&&s[k+1]!=s[q]){ k=next[k];//往前回溯 } if(s[k+1]==s[q]){ k=k+1; } //这个是把算的k的值(就是相同的最大前缀或最大后缀的长度减去1)赋给next[q] next[q]=k; } return next; } }
2.变形词判断
import java.util.*; //变形词判断 public class Transform { public boolean chkTransform(String A, int lena, String B, int lenb) { if(A==null||B==null||A.length()!=B.length()){ return false; } //对A建立哈希数组 int[] map=new int[256];//0-255是ASCII码对应的十进制编码 int lenA=A.length(); int lenB=B.length(); char[] Aarray=A.toCharArray(); char[] Barray=B.toCharArray(); for(int i=0;i<lenA;i++){ map[Aarray[i]]++; } //遍历B查询A的哈希数组,看是否对应 for(int i=0;i<lenB;i++){ if(map[Barray[i]]--==0){ return false; } } return true; } }
3.两串旋转练习题
如果对于一个字符串A,将A的前面任意一部分挪到后边去形成的字符串称为A的旋转词。比如A=”12345”,A的旋转词有”12345”,”23451”,”34512”,”45123”和”51234”。对于两个字符串A和B,请判断A和B是否互为旋转词。给定两个字符串A和B及他们的长度lena,lenb,请返回一个bool值,代表他们是否互为旋转词。
测试样例:
“cdab”,4,”abcd”,4
返回:true
import java.util.*; public class Rotation { public boolean chkRotation(String A, int lena, String B, int lenb) { char[] Aarray=(A+A).toCharArray(); int[] next=cal_next(B); char[] Barray=B.toCharArray(); int len=Aarray.length; int lenB=B.length(); //使用KMP算法计算B是否包含在A+A中 int k=-1; for(int i=0;i<len;i++){ while(k>-1&&Barray[k+1]!=Aarray[i]){ k=next[k]; } if(Barray[k+1]==Aarray[i]){ k=k+1; } if(k==(lenB-1)){ //return i-lenp+1; return true; } } return false; } //计算next数组 public int[] cal_next(String str){ char[] s=str.toCharArray(); int len=str.length(); int[] next=new int[len]; next[0]=-1; int k=-1; for(int q=1;q<=(len-1);q++){ //如果下一个不同,那么k就变成next[k],注意next[k]是小于k的,无论k取任何值。 while(k>-1&&s[k+1]!=s[q]){ k=next[k];//往前回溯 } if(s[k+1]==s[q]){ k=k+1; } //这个是把算的k的值(就是相同的最大前缀和最大后缀长)赋给next[q] next[q]=k; } return next; } }
4.字符串逆序
方法一:使用split函数分离出单词
import java.util.*; //字符串逆序 public class Reverse { public String reverseSentence(String A, int n) { String reverseA=reverse(A); String[] words=reverseA.split(" "); int len=words.length; String result=new String(); for(int i=0;i<len;i++){ result+=reverse(words[i]); if(i<len-1){ result+=" "; } } return result; } //调整字符串为逆序 public String reverse(String s){ char[] a=s.toCharArray(); int len=a.length; int left=0,right=len-1; while(left<right){ char temp=a[left]; a[left]=a[right]; a[right]=temp; left++; right--; } return String.valueOf(a); } }
方法二:自动判断单词
import java.util.*; //字符串逆序 public class Reverse { public String reverseSentence(String A, int n) { char[] a=A.toCharArray(); rotateWord(a); return String.valueOf(a); } public void rotateWord(char[] a){ //整个字符串进行逆序 reverse(a,0,a.length-1); //对单词再进行逆序 int left=-1,right=-1;//left指向单词的第一个,right指向单词最后一个 int len=a.length; for(int i=0;i<len;i++){ if(a[i]!=' '){ left=i==0||a[i-1]==' '?i:left; right=i==len-1||a[i+1]==' '?i:right; } //left和right分别指向了单词的第一个和最后一个时 if(left!=-1&&right!=-1){ reverse(a,left,right); left=-1; right=-1; } } } //调整字符串为逆序 public void reverse(char[] a,int start,int end){ while(start<end){ char temp=a[start]; a[start]=a[end]; a[end]=temp; start++; end--; } } }
5.字符串移位
import java.util.*; //原地字符串移位练习 public class Translation { public String stringTranslation(String A, int n, int len) { char[] a=A.toCharArray(); //将字符串0-(len-1)部分逆序 reverse(a,0,len-1); //将字符串len到最后的部分逆序 reverse(a,len,a.length-1); //将整个字符串逆序 reverse(a,0,a.length-1); return String.valueOf(a); } //局部逆序操作 public void reverse(char[] a,int start,int end){ while(start<end){ char temp=a[start]; a[start]=a[end]; a[end]=temp; start++; end--; } } }
6. 拼接最小字典序练习题
对于一个给定的字符串数组,请找到一种拼接顺序,使所有小字符串拼接成的大字符串是所有可能的拼接中字典序最小的。给定一个字符串数组strs,同时给定它的大小,请返回拼接成的串。
测试样例:
[“abc”,”de”],2
“abcde”
import java.util.*; //拼接最小字典序列 public class Prior { public String findSmallest(String[] strs, int n) { Arrays.sort(strs,new Comparator<String>(){ @Override public int compare(String a,String b){ return (a+b).compareTo(b+a); } }); String result=new String(); for(int i=0;i<n;i++){ result+=strs[i]; } return result; } }
7. 空格替换
import java.util.*; //字符串空格替换 public class Replacement { public String replaceSpace(String iniString, int length) { //首先遍历字符串找到空格的数量以确定替换后的总长度 int space=0; char[] s=iniString.toCharArray(); for(int i=0;i<length;i++){ if(s[i]==' '){ space++; } } int total=length+2*space;//替换后的字符个数 char[] result=new char[total]; //将字符依次拷贝到后面的空间,遇到空格时替换为%20 for(int i=length-1,index=total-1;i>=0&&index>=0;i--,index--){ if(s[i]!=' '){ result[index]=s[i]; }else{ result[index--]='0'; result[index--]='2'; result[index]='%'; } } return String.valueOf(result); } }
直接使用StringBuilder
import java.util.*; //字符串空格替换 public class Replacement { public String replaceSpace(String iniString, int length) { //将字符依次拷贝到后面的空间,遇到空格时替换为%20 StringBuilder sb=new StringBuilder(); for(int i=0;i<length;i++){ char c=iniString.charAt(i); if(c==' '){ sb.append("%20"); }else{ sb.append(c); } } return sb.toString(); } }
8.合法括号判断
import java.util.*; //合法括号串判断 public class Parenthesis { public boolean chkParenthesis(String A, int n) { int num=0; Stack<String> stack=new Stack<String>(); for(int i=0;i<n;i++){ char c=A.charAt(i); if(c=='('){ stack.push("("); continue; } if(c==')'){ if(stack.isEmpty()==true||stack.pop()!="("){ return false; } } } return stack.isEmpty(); } }
9.最长无重复子串
import java.util.*; //最长无重复子串长度计算 public class DistinctSubstring { public int longestSubstring(String A, int n) { //哈希表map记录每种字符最近出现的位置 //pre记录当前字符的上一个字符串结尾的情况下,最长无重复字符子串的起始位置-1 int[] map=new int[256]; for(int i=0;i<256;i++){ map[i]=-1; } int max=0,pre=-1,temp=0; for(int i=0;i<n;i++){ pre=Math.max(pre,map[A.charAt(i)]); temp=i-pre; max=Math.max(max,temp); map[A.charAt(i)]=i; } return max; } }
3.JAVA实现tips
* String的长度用length() * “ ”双引号表示空字符串,‘ ’单引号表示空字符 * 字符数组转换成String,String.valueOf(char[] ch) * compareTo()方法 http://www.runoob.com/java/number-compareto.html * StringBuilder() 增加字符串append("XXX") * StringBuilder转换为String类型 toString() * String获取字符元素 s.charAt(index)
相关文章推荐
- 算法与数据结构-排序 讲解与java代码实现
- 算法与数据结构-链表 讲解与java代码实现
- 算法与数据结构-栈与队列 讲解与java代码实现
- 算法与数据结构-二分搜索 讲解与java代码实现
- 算法与数据结构-动态规划 讲解与java代码实现
- 算法与数据结构-二叉树 讲解与java代码实现
- 程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现
- 【算法与数据结构】冒泡、插入、归并、堆排序、快速排序的Java实现代码
- 线索二叉树代码实现 - 数据结构和算法49
- 无限级分类的简单算法实现及代码重点讲解。
- Java字符串反转算法实现
- 线索二叉树代码实现 - 数据结构和算法49
- 关键路径(代码讲解)- 数据结构和算法68
- 数据结构C语言实现之链式队列的6种算法代码
- java 算法40题 有实现代码
- 关键路径(代码讲解)- 数据结构和算法68
- 问题1:java中没有实现这种“byte a = 0xB2 --> String b = “B2””转换的简单实现需要自己实现。 答:自己编写的转换函数,思路将byte的高低4位分开,分别转换为对应的字符然后合成返回的字符串。 java 代码 1.
- java实现编辑距离算法,计算字符串相似度
- 严蔚敏《数据结构》中迷宫算法java实现
- C++类模板 实现队列的链式存储结构算法 《数据结构》(北京科海) 部分代码摘抄,自己编写运行