1.如何求一个字符串的所有排序
题目描述:
实现一个方法,当输入一个字符串时,要求输出这个字符串的所有排列。例如,输入字符串abc,要求输出由字符a、b、c所能排列出来的所有字符串:abc,acb,bac,bca,cab,cba。
public class SoftStringDemo1 {
//交互字符串数组下标i和j对应的字符
private static void swap(char[] str,int i, int j){
char tmp =str[i];
str[i]=str[j];
str[j]=tmp;
}
//对字符串中的字符进行全排序
public static void Permutation(char[] str,int start){
if(str==null||start<0)
return;
//完全全排序后输出当前排序的字符串
if(start==str.length-1)
System.out.println(str);
else
{
for(int i=start;i<str.length;i++){
//交换start 与i 所在位置的字符
swap(str,start,i);
//固定第一个字符,对剩余的字符进行全排列
Permutation(str,start+1);
//还原 start 与i 所在 位置的字符
swap(str,start,i);
}
}
}
public static void Permutation(String s){
char[] str=s.toCharArray();
Permutation(str,0);
}
public static void main(String[] args) {
String s="abc";
Permutation(s);
}
}
2.如何去掉重复的排列
题目描述:
当字符串中没有重复的字符时,它的所有组合对应的字符串也就没有重复的情况,但是当字符串中有重复的字符时,例如“baa”,此时如果按照上面介绍的算法求全排列的时候就会有重复的字符串。
package string;
public class RepeatSoftDemo {
//交换字符数组下标为i和j对应的字符
private static void swap(char[] str,int i, int j){
char tmp=str[i];
str[i]=str[j];
str[j]=tmp;
}
//判断begin ,end 区间中是否有字符与*end相等
private static boolean isDuplicate(char[] str,int begin, int end){
for(int i=begin; i<end;i++){
if(str[i]==str[end])
return false;
}
return true;
}
//对字符串的字符全排列
public static void Permutation(char[] str,int start){
if(str==null||start<0)
return;
//完全排列后输出当前排列的字符串
if(start==str.length-1)
System.out.print(new String(str)+" ");
else {
for(int i=start; i<str.length;i++){
if(!isDuplicate(str,start,i))
continue;
//交换start与i所在位置的字符
swap(str,start,i);
Permutation(str,start+1);
swap(str,start,i);
}
}
}
public static void Permutation(String s){
char[] str=s.toCharArray();
Permutation(str,0);
}
public static void main(String[] args) {
String s="aba";
Permutation(s);
}
}
3.如何判断两个字符串的包含关系
题目描述:
给定由字母组成的字符串s1和s2,其中,s2中字母的个数少于s1,如何判断s1是否包含s2?即出现在s2中的字符在s1中都存在。例如,s1=“abcdef”,s2=“acf”,那么s1就包含s2;如果s1=“abcdef”,s2=“acg”,那么s1就不包含s2,因为s2中有“g”,但是s1中没有g。
package string;
/**
* @author 龙御修
* @create 2022-05-15 10:35
*/
public class ContainString {
public static boolean isContain(String s1,String s2){
int i;
int k=0; //字母对应数组的下标
int[] flag=new int[52];//用来记录52个字母的出现情况
for(i=0;i<52;i++){
flag[i]=0;
}
int count=0; //记录段字符串中不同字符出现的个数
int len1=s1.length();
int len2=s2.length();
String shortStr,longStr;//较短,较长的字符串
int maxLen, minLen; //较短长度和较长长度
if(len1<len2){
shortStr=s1;
minLen=len1;
longStr=s2;
maxLen=len2;
}else {
shortStr=s2;
minLen=len2;
longStr=s1;
maxLen=len1;
}
//遍历短字符串
for(i=0;i<minLen;i++){
//把字符装换成数组对应的下标(大写字母0~25,小写字母26~51)
if(shortStr.charAt(i)>='A'&&shortStr.charAt(i)<='Z')
k=shortStr.charAt(i)-'A';
else
k=shortStr.charAt(i)-'a'+26;
if(flag[k]==0){
flag[k]=1;
count++;
}
}
//遍历长字符串
for(int j=0;j<maxLen;j++){
if(longStr.charAt(j)>='A'&&longStr.charAt(j)<='Z')
k=longStr.charAt(j)-'A';
else
k=longStr.charAt(j)-'a'+26;
if(flag[k]==1){
flag[k]=0;
count--;
if(count==0)
return true;
}
}
return false;
}
public static void main(String[] args) {
String str1="abcdef";
String str2="acf";
boolean isContain=isContain(str1,str2);
System.out.println(str1+"与"+str2);
if(isContain)
System.out.println("有包含关系");
else
System.out.println("没有包含关系");
}
}
4.如何消除字符串的内嵌括号
题目描述:
给定一个如下格式的字符串:(1,(2,3),(4,(5,6),7)),括号内的元素可以是数字,也可以是另一个括号,实现一个算法消除嵌套的括号。例如,把上面的表达式变成 (1,2,3,4,5,6,7),如果表达式有误,则报错。
/**
* @author 龙御修
* @create 2022-05-15 11:11
*/
public class NestedString {
//去掉字符串中的嵌套的括号
public static String removeNestedPare(String str){
if(str==null)
return str;
int Parentheses_num=0;//用来记录不匹配的"("出现的次数
if(str.charAt(0)!='('||str.charAt(str.length()-1)!=')')
return null;
StringBuffer sb=new StringBuffer("(");
char ch;
//字符串首位的括号可以单独处理
for(int i=1;i<str.length()-1;i++){
ch=str.charAt(i);
if(ch=='(')
Parentheses_num++;
else if(ch==')')
Parentheses_num--;
else
sb.append(str.charAt(i));
}
//判断括号是否匹配
if(Parentheses_num!=0){
System.out.println("由于括号不匹配,因此不做操作");
return null;
}
//处理字符串结尾的")"
sb.append(")");
return sb.toString();
}
public static void main(String[] args) {
String str = "(1,(2,3),(4,(5,6),7))";
System.out.println(str+"去除嵌套括号后为:"+removeNestedPare(str));
}
}
5.如何求解字符串中字典序最大的子序列
题目描述:
给定一个字符串,求串中字典序最大的子序列。字典序最大的子序列是这样构造的:给定字符串a0a1…an-1,首先在字符串a0a1…an-1找到值最大的字符ai,然后在剩余的字符串ai+1…an-1中找到值最大的字符aj,然后在剩余的aj+1…an-1中找到值最大的字符ak…。依此类推,直到字符串的长度为0,则aiajak…即为答案。
字典序(dictionary order),又称 字母序(alphabetical order),原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。
/**
* @author 龙御修
* @create 2022-05-15 18:21
*/
public class DictionaryString {
public static String getLargestSub(String src){
if(src==null){
return null;
}
char[] largestSub=src.toCharArray();
//最后一个字符一定在子串中
largestSub[0] = src.charAt(largestSub.length - 1);
int j=0;
//逆序遍历字符串
for(int i=largestSub.length-2;i>=0;i--){
if(src.charAt(i)>=largestSub[j]){
largestSub[++j]=src.charAt(i);
}
}
//记录一下字符串的长度
int length = j + 1;
//对子串进行逆序
for(int i=0;i<j;i++,j--){
char tmp=largestSub[i];
largestSub[i] = largestSub[j];
largestSub[j]=tmp;
}
return new String(largestSub,0,length);
}
public static void main(String[] args) {
String s="acbdxmng";
String result = getLargestSub(s);
if(result==null){
System.out.println("字符串为空");
}else {
System.out.println(result);
}
}
}
6.如何截取包含中文的字符串
题目描述:
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,例如“人ABC”4,应该截为"人AB",输入“人ABC们DEF”, 6,应该输出为“人ABC”而不是“人ABC”+“们”的半个。
英文占用一个字符,中文占用2个字符
package string;
/**
* @author 龙御修
* @create 2022-05-15 18:38
*/
public class ChineseString {
//判断字符串是否为中文字符
public static boolean isChinese(char c) {
String sb = String.valueOf(c);
return sb.getBytes().length > 1;
}
public String truncateStr(String str, int len) {
if (str == null || str.equals("") || len == 0)
return "";
char[] charArr = str.toCharArray();
StringBuilder sb = new StringBuilder("");
int count = 0;//记录当前截取字符串的长度
for (char cc : charArr) {
if (count < len) {
if (isChinese(cc)) {
//如果要求截取子串的长度之差一个一个字符,但是接下来是中文
//则截取结果子串中不保存这个中文字符
if (count + 1 == len)
return sb.toString();
count = count + 2;
} else {
count=count+1;
}
sb = sb.append(cc);
}else {
break;
}
}
return sb.toString();
}
public static void main(String[] args) {
ChineseString cs=new ChineseString();
String sb="人ABC们DEF";
System.out.println(cs.truncateStr(sb,6));
}
}
7.如何求相对路径
题目描述:
编写一个函数,根据两个文件的绝对路径算出其相对路径。例如,a="/qihoo/app/a/b/c/d/new.c",b="/qihoo/app/1/2/test.c",那么b相对于a的相对路径是"../../../../1/2/test.c"。
package string;
/**
* @author 龙御修
* @create 2022-05-15 19:01
*/
public class PathString {
public static String getRelativePath(String path1,String path2){
if(path1==null||path2==null){
System.out.println("参数不合法\n");
return null;
}
String relativePath="";//相对路径
int diff1=0;
int diff2=0;//用来指向两个路径中不同目录起始路径
int j=0;
int i=0;
int len1=path1.length();
int len2=path2.length();
while (i<len1&&j<len2){
//如果,目录相同则往后遍历
if(path1.charAt(i)==path2.charAt(j)){
if('/' == path1.charAt(i)){
diff1=i;
diff2=j;
}
i++;
j++;
}else{//不同的目录
//把path1非公公共部分的目录转换为../
diff1++;//跳过目录分隔符
while (diff1<len1){
//碰到下一级目录
if(path1.charAt(diff1)=='/'){
relativePath+="../";
}
diff1++;
}
//把path2的非公共部分的路径加到后面
diff2++;
relativePath+=path2.substring(diff2);
break;
}
}
return relativePath;
}
public static void main(String[] args) {
String a="/qihoo/app/a/b/c/d/new.c";
String b="/qihoo/app/1/2/test.c";
System.out.println(getRelativePath(a,b));
}
}