202205014java算法笔试题----String(字符串)

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));
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Royalreairman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值