【算法设计与分析(课后答案)】字符串

1. 求解两种排序方法问题

【问题描述】考拉有n个字符串字符串,任意两个字符串长度都是不同的。考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序(“car” < “carriage” < “cats” < "doggies < “koala”);2.根据字符串的长度排序(“car” < “cats” < “koala” < “doggies” < “carriage”)。考拉想知道自己的这些字符串排列顺序是否满足这两种排序方法,考拉要忙着吃树叶,所以需要你来帮忙验证。

【输入描述】输入第一行为字符串个数n(n ≤ 100)接下来的n行,每行一个字符串,字符串长度均小于100,均由小写字母组成
【输出描述】如果这些字符串是根据字典序排列而不是根据长度排列输出"lexicographically",如果根据长度排列而不是字典序排列输出"lengths",如果两种方式都符合输出"both",否则输出"none"

【输入样例】3
         a
         aa
         bbb
【输出样例】both

public class Solution1 {
    
    

    public String kindOfSort(String[] arr) {
    
    
        String res = "";
        if(sortByDict(arr) && sortByLen(arr)) {
    
    
            res = "both";
        } else if (sortByDict(arr) && !sortByLen(arr)) {
    
    
            res = "islexicalorder";
        } else if (!sortByDict(arr) && sortByLen(arr)) {
    
    
            res = "lengths";
        } else {
    
    
            res = "none";
        }
        return res;
    }

    // 按字典序排序
    private boolean sortByDict(String[] arr) {
    
    
        for (int i = 1; i < arr.length; i++) {
    
    
            if (arr[i].compareTo(arr[i - 1]) < 1) {
    
    
                return false;
            }
        }
        return true;
    }

    // 按长度排序
    private boolean sortByLen(String[] arr) {
    
    
        for (int i = 1; i < arr.length; i++) {
    
    
            if (arr[i].length() < arr[i - 1].length()) {
    
    
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[] arr = new String[n];
        for (int i = 0; i < n; i++) {
    
    
            arr[i] = sc.next();
        }
        System.out.println(new Solution1().kindOfSort(arr));
    }
}

2. 求解删除公共字符串问题

【问题描述】输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
【输入描述】每个测试输入包含2个字符串
【输出描述】输出删除后的字符串

【输入样例】They are students.
         aeiou
【输出样例】Thy r stdnts.

public class Solution2 {
    
    

    /**
     * 放开思路———在原串上删是很麻烦的,因为删除操作会改变下标;因此不妨从头开始构建一个新串
     */
    public String delPublicChar(String s1, String s2) {
    
    
        Set<Character> set = new HashSet<>();
        for (char c : s2.toCharArray()) {
    
    
            set.add(c);
        }
        StringBuilder sb = new StringBuilder();
        for (char c : s1.toCharArray()) {
    
    
            if (!set.contains(c)) {
    
    
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        System.out.println(new Solution2().delPublicChar(s1, s2));
    }
}

3. 求解移动字符串问题

【问题描述】设计一个函数将字符串中的字符’*‘移动到串的前面部分,前面的非’‘字符后移,但不能改变非’‘字符的先后顺序,函数返回串中字符’*'的数量。如原始串为"ab**cd**e*12",处理后为"*****abcde12",函数返回值为5(要求使用尽量少的时间和辅助空间)。

【输入描述】原字符串
【输出描述】输出分为两行。第一行为修改后的字符串,第二行为字符串中“*”的个数

【输入样例】ab**cd**e*12
【输出样例】*****abcde12
         5

public class Solution3 {
    
    

    /**
     * 依旧是要打开思路———不要在原串上移动,而是从头构建新串
     */
    public void moveChar(String s) {
    
    
        StringBuilder sb = new StringBuilder();
        int cnt = 0;
        for (char c : s.toCharArray()) {
    
    
            if (c == '*') {
    
    
                cnt++;
                sb.insert(0, '*');
            } else {
    
    
                sb.append(c);
            }
        }
        System.out.println(sb.toString());
        System.out.println(cnt);
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        new Solution3().moveChar(s);
    }
}

4. 求解大整数相乘问题

【问题描述】有两个用字符串表示的非常大的大整数,算出它们的乘积,也用字符串表示,不能用系统自带的大数据类型。

【输入描述】一行输入,两个字符串中间用空格隔开
【输出描述】输出的乘积也用字符串表示

【输入样例】72106547548473106236 982161082872751395
【输出样例】70820244829634538040848656466105986748

public class Solution4 {
    
    

    /**
     * 这是目前为止我认为最优雅的的写法
     */
    public String bigNumMultiply(String num1, String num2) {
    
    
        if (num1.equals("0") || num2.equals("0")) {
    
    
            return "0";
        }
        int len1 = num1.length();
        int len2 = num2.length();
        int[] res = new int[len1 + len2];

        for (int i = 0; i < len1; i++) {
    
    
            for (int j = 0; j < len2; j++) {
    
    
                int n1 = num1.charAt(i) - '0';
                int n2 = num2.charAt(j) - '0';
                int n3 = res[i + j + 1] + n1 * n2;
                res[i + j + 1] = n3 % 10;
                res[i + j] += n3 / 10;
            }
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < res.length; i++) {
    
    
            if (i == 0 && res[i] == 0) {
    
    
                continue;
            }
            sb.append(res[i]);
        }
        return sb.toString();

    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        String num1 = sc.next();
        String num2 = sc.next();
        System.out.println(new Solution4().bigNumMultiply(num1, num2));
    }
}

5. 求解旋转词问题

【问题描述】如果字符串t是字符串s的后面若千个字符循环右移得到的.称s和t是旋转词,例如"abedef"和"efabed"是旋转词,而"abedef"和"feabcd"旋转词。

【输人描述】第1行为n(1≤n≤100),接下来的n行,每行两个字符串,以空格分隔。
【输出描述】输出n行,若输人的两个字符串是旋转词,输出"Yes",否则输出"No"。

【输入样例】2
         abedef efabed
         abedef feabed
【样例输出】Yes
         No

public class Solution5 {
    
    

    /**
     * 很经典的字符串问题
     */
    public boolean isRotateString(String s1, String s2) {
    
    
        return s1.length() == s2.length() && (s1 + s1).indexOf(s2) >= 0;
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[][] inputs = new String[n][2];
        for (int i = 0; i < n; i++) {
    
    
            inputs[i][0] = sc.next();
            inputs[i][1] = sc.next();
        }
        Solution5 solution5 = new Solution5();
        for (String[] input : inputs) {
    
    
            System.out.println(solution5.isRotateString(input[0], input[1]) ? "Yes" : "No");
        }
    }
}

6. 求解门禁系统问题

【问题描述】涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,得到每一条记录中的读者是第几次出现。

【输人描述】输入的第1行包含一个整数n,表示涛涛的记录条数;第2行包含n个整数,一次表示涛涛的记录中每位读者的编号。
【输出描述】输出一行,包含n个整数,由空格分隔,依次表示每条记录中的蹙着编号是第几次出现。

【输入样例】5
         1 2 1 1 3
【样例输出】Yes
         1 1 2 3 1

public class Solution6 {
    
    

    /**
     * 简单的HashMap的使用
     */
    public int[] entranceGuard(int[] arr) {
    
    
        int len = arr.length;
        int[] res = new int[len];
        Map<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < len; i++) {
    
    
            map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
            res[i] = map.get(arr[i]);
        }
        return res;
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
    
    
            arr[i] = sc.nextInt();
        }
        System.out.println(Arrays.toString(new Solution6().entranceGuard(arr)));
    }
}

7. 求解数字排序问题

【问题描述】给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。

【输入描述】输入的第1行包含一个整数n,表示给定整数的个数;第2行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
【输出描述输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数,按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。最后一行也有回车

【 输入样例】12
         5 2 3 3 1 3 4 2 5 2 3 5
【样例输出】3 4
         2 3
         5 3
         1 1
         4 1

public class Solution7 {
    
    

    /**
     * 这其实是一个看似简单但实则很难的题目———HashMap本身无序,我们又如何对HashMap进行排序呢?
     * 找个操作你可能很少见到:将HashMap的一个个Entry<Key,Value>放到List当中,并重写其比较器
     */
    public void countAndSort(int[] nums) {
    
    
        Map<Integer, Integer> map = new HashMap<>();
        for (int n : nums) {
    
    
            map.put(n, map.getOrDefault(n, 0) + 1);
        }
        List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
    
    
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
    
    
                if (o1.getValue() != o2.getValue()) {
    
    
                    return o2.getValue() - o1.getValue();
                } else {
    
    
                    return o1.getKey() - o2.getKey();
                }
            }
        });
        for (Map.Entry<Integer, Integer> entry : list) {
    
    
            System.out.print(entry.getKey());
            System.out.println(entry.getValue());
        }
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
    
    
            nums[i] = sc.nextInt();
        }
        new Solution7().countAndSort(nums);
    }
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

⭐️ 这一定是全网最优美的Java解法 >_<

猜你喜欢

转载自blog.csdn.net/m0_46202073/article/details/115034890
今日推荐