计算机算法设计与分析(王晓东著)第一章算法实现题解

计算机算法设计与分析(王晓东著)第一章算法实现题解

在这里插入图片描述

思想:借助辅助数组num去统计0-9出现的次数即可。

case1:直接在控制台输入输出。

import java.util.Arrays;
import java.util.Scanner;

public class CountNumber {
    public static void countNumber(int n, int [] num){
        Arrays.fill(num, 0) ;
        for(int i=1; i<=n; i++){
            String s = String.valueOf(i) ;
            for(int j=0; j<s.length(); j++){
              num[s.charAt(j) - '0'] ++ ;
            }
        }
        for(int i=0; i<num.length; i++){
            System.out.println(num[i]) ;
        }
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int n = input.nextInt() ;
        int [] num = new int [10] ;
        countNumber(n, num) ;
    }
}

case2: 通过读取input.txt文件的测试数据,测试结果输出到output.txt文件。
在D盘的study文件夹下创建input.txt文件和output.txt文件,并在input.txt文件中输入测试数据,运行程序,结果将在output.txt文件输出。

import java.io.*;
import java.util.Arrays;

public class CountNumber {
    public static String line  ;
    public static int []  countNumber(int n, int [] num){
        Arrays.fill(num, 0) ;
        for(int i=1; i<=n; i++){
            String s = String.valueOf(i) ;
            for(int j=0; j<s.length(); j++){
              num[s.charAt(j) - '0'] ++ ;
            }
        }
      return num ;
    }
    public static void main(String[] args) {
        int[] num = new int[10];
        try (FileInputStream input = new FileInputStream("D:\\study\\input.txt");
           DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(input))){
            line = dataInputStream.readLine() ;
        } catch (FileNotFoundException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
        }
        System.out.println("文件读取成功!!!");

        try ( FileOutputStream output = new FileOutputStream("D:\\study\\output.txt");
           DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(output))){
            int [] res = countNumber(Integer.parseInt(line), num) ;
            for(int i=0; i<res.length; i++) {
               dataOutputStream.writeBytes(res[i] + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件写入成功!!!");
    }
}

在这里插入图片描述

import java.util.Scanner;

public class Lexicographic1 {
    //第i位字符开头,长度为k的升序序列个数
    public static int f(int i, int k){
        int sum = 0 ;
        if(k == 1){
            return 1 ;
        }else{
            sum += f(i, k-1) ;
        }
        return sum ;
    }
    //字符串长度为k的所有长度的总个数
    public static int g(int k){
        int sum = 0 ;
        for(int i=1; i<=26; i++){
            sum += f(i,k) ;
        }
        return sum ;
    }
    public static int getResult(String s){
        int len = s.length() ;
        int sum = 0 ;
        for(int i=1; i<len; i++){ //长度小于len位的各个位的升序序列的总和
            sum += g(i) ;
        }
        char [] c = s.toCharArray() ;
        int head = c[0] - 'a' + 1 ;
        for(int i=1; i<head; i++){  //长度等于len位的以head之前的字母打头的序列总和
            sum += f(i, len) ;
        }
        //计算以head打头的剩下字符,长度等于len位的到字符串s之前的序列总和
        for (int i = 1,temp = head; i < len; i++) {
            int str2 = c[i]-'a'+1;
            int len2 =  len-i;
            for (int j = temp+1; j < str2; j++) {
                sum+=f(j,len2);
            }
            temp=str2;
        }
        return sum + 1 ;
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int n = input.nextInt() ;
        String [] num = new String [n] ;
        for(int i=0; i<num.length; i++){
            num[i] = input.next() ;
        }
        for(int j=0; j<n; j++) {
            System.out.println(getResult(num[j]));
        }
    }
}

在这里插入图片描述
case1:直接在控制台输入输出。

import java.util.Scanner;

public class Approximate {
    public static int count(int n){
        int sum = 0 ;
        for(int i=1; i<=n; i++){
            if(n % i == 0){
                sum ++ ;
            }
        }
        return sum ;
    }
    public static int findNumber(int a, int b){
        int max = 0 ;
        for(int i=a; i<=b; i++){
            max = Math.max(max, count(i)) ;
        }
        return max ;
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int a = input.nextInt() ;
        int b = input.nextInt() ;
        System.out.println(findNumber(a, b));
    }
}

case 2:通过读取input.txt文件的测试数据,测试结果输出到output.txt文件。
在D盘的study文件夹下创建input.txt文件和output.txt文件,并在input.txt文件中输入测试数据,运行程序,结果将在output.txt文件输出。

import java.io.*;

public class Approximate2 {
    public static String line = "" ;
    public static String [] num ;
    public static int count(int n){
        int sum = 0 ;
        for(int i=1; i<=n; i++){
            if(n % i == 0){
                sum ++ ;
            }
        }
        return sum ;
    }
    public static int findNumber(int a, int b){
        int max = 0 ;
        for(int i=a; i<=b; i++){
            max = Math.max(max, count(i)) ;
        }
        return max ;
    }
    public static void main(String[] args) {
        try (FileInputStream input = new FileInputStream("D:\\study\\input.txt");
             DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(input))){
            line = dataInputStream.readLine() ;
           num = line.split("[ ]") ;
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        System.out.println("文件读取成功!!!");

        try ( FileOutputStream output = new FileOutputStream("D:\\study\\output.txt");
              DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(output))){
            int res = findNumber(Integer.parseInt(num[0]), Integer.parseInt(num[1])) ;
                dataOutputStream.writeBytes(res + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件写入成功!!!");
    }
    }

在这里插入图片描述
case1:控制台输入输出。

import java.util.Scanner;

public class Main {
    public static int count = 0 ;
    public static boolean flag ;
    public static void swap(int [][] arr1, int c1, int c2){ //交换矩阵的两列
        for(int i=0; i<arr1.length; i++){
            int temp = arr1[i][c1] ;
            arr1[i][c1] = arr1[i][c2] ;
            arr1[i][c2] = temp ;
        }
        if(c1 != c2){
            count ++ ;
        }
    }
    public static boolean sameColumn(int [][] arr1, int [][] arr2, int c1, int c2){ //判断两个矩阵两列元素是否完全相同
        for(int i=0; i<arr1.length; i++){
            if(arr1[i][c1] != arr2[i][c2]){
                return false ;
            }
        }
        return true ;
    }
    public static void reverseRow(int [][] arr1, int row){ //将矩阵的某行翻转
        for(int i=0; i<arr1[0].length; i++){
            arr1[row][i] = arr1[row][i] ^ 1 ;
        }
        count ++ ;
    }
    public static void copy(int [][] arr1, int [][] arr2, int m ,int n){ //复制矩阵
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                arr1[i][j] = arr2[i][j] ;
            }
        }
    }
    public static int find(int [][] arr1, int [][] arr2, int m, int n){

        int [][] temp = new int [m][n] ;
        int min = m + n + 1 ;
        copy(temp, arr1, m, n) ;
        for(int i=0; i<n; i++){ //每一列作为第一列
            swap(arr1, i, 0) ;
            for(int j=0; j<m; j++){
                if(arr1[j][0] != arr2[j][0]){
                    reverseRow(arr1, j);
                }
            }
            for(int j=0; j<n; j++){
                flag = false ;
                for(int k=j; k<n; k++){
                    if(sameColumn(arr1, arr2, j, k)){
                        swap(arr1, j, k) ;
                        flag = true ;
                        break ; //跳出内层循环
                    }
                    if(!flag){ //没有符合条件的
                        break ;
                }

                }
            }
            if(flag && count < min){
                min = count ;
            }
            count = 0 ;
           copy(arr1, temp, m, n);
        }
        if(min < m + n + 1){
            return min ;
        }else{
            return -1 ;
        }
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n1 = input.nextInt();
        int [] res = new int [n1] ;
        int l = 0 ;
        while (n1 > 0) {
            int m = input.nextInt() ;
            int n = input.nextInt() ;
            int [][] arr1 = new int [m][n] ;
            int [][] arr2 = new int [m][n] ;
            for(int i=0; i<m; i++){
                for(int j=0; j<n; j++){
                    arr1[i][j] = input.nextInt() ;
                }
            }
            for(int i=0; i<m; i++){
                for(int j=0; j<n; j++){
                    arr2[i][j] = input.nextInt() ;
                }
            }
           res[l] = find(arr1, arr2, m, n) ;
            l ++ ;
            n1 -- ;
        }
        for(int i=0; i<res.length; i++){
            System.out.println(res[i] );
        }
    }
}

case 2:通过读取input.txt文件的测试数据,测试结果输出到output.txt文件。
在D盘的study文件夹下创建input.txt文件和output.txt文件,并在input.txt文件中输入测试数据,运行程序,结果将在output.txt文件输出。
此部分略,把键盘读取换成IO流读取和输出即可。
在这里插入图片描述

case1:直接在控制台输入输出。
思想:先按升序排序,然后依次求间隔,比较找出最大的。
当然,这样,时间复杂度就不是线性了。
要想时间复杂度为线性,要用到鸽笼原理。

import java.util.Arrays;
import java.util.Scanner;

public class MaximalClearance {

    public static float max(float [] num){
        Arrays.sort(num); ;
        float res = Float.MIN_VALUE ;
        for(int i=0; i<num.length-1; i++){
            float interval = num[i+1] - num[i] ;
            if(interval >= res){
                res = interval ;
            }
        }
        return res ;
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int n = input.nextInt() ;
        float [] num = new float [n] ;
        for(int i=0; i<n; i++){
                num[i] = input.nextFloat() ;
        }
        System.out.printf("%.1f",max(num));
    }
}

case 2:通过读取input.txt文件的测试数据,测试结果输出到output.txt文件。
在D盘的study文件夹下创建input.txt文件和output.txt文件,并在input.txt文件中输入测试数据,运行程序,结果将在output.txt文件输出。

import java.io.*;
import java.util.Arrays;

public class MaximalClearance1 {
    public static String line ;
    public static int n ;
    public static float [] num ;
    public static float max(float [] num){
        Arrays.sort(num); ;
        float res = Float.MIN_VALUE ;
        for(int i=0; i<num.length-1; i++){
            float interval = num[i+1] - num[i] ;
            if(interval >= res){
                res = interval ;
            }
        }
        res = Float.parseFloat(String.format("%.1f", res)) ;
        return res ;
    }
    public static void main(String[] args) {
        try (FileInputStream input = new FileInputStream("D:\\study\\input.txt");
             DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(input))){
            line = dataInputStream.readLine() ;
            n = Integer.parseInt(line) ;
            while(line != null){
                line = dataInputStream.readLine() ;
               String [] s = line.split("[ ]") ;
               num  = new float [s.length] ;
               for(int i=0; i<s.length; i++){
                   num[i] = Float.parseFloat(s[i]) ;
               }
                line = dataInputStream.readLine() ;
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        System.out.println("文件读取成功!!!");

        try ( FileOutputStream output = new FileOutputStream("D:\\study\\output.txt");
              DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(output))){
              float  res = max(num) ;
                dataOutputStream.writeBytes(res + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件写入成功!!!");
    }
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,你的问题是关于哈夫曼编码的C++实现。我会尽力回答。 首先,哈夫曼编码是一种变长编码,用于数据的压缩和解压缩。它基于一个前缀编码树,树的每个叶子节点代表一个数据项,并且每个非叶子节点代表一个编码前缀。哈夫曼编码可以将出现频率较高的数据项用较短的编码表示,出现频率较低的数据项用较长的编码表示,从而达到压缩的目的。 下面是一个简单的C++实现示例,参考自《计算机算法设计与分析王晓东: ```c++ #include <iostream> #include <queue> #include <vector> using namespace std; struct Node{ int freq; char data; Node* left; Node* right; Node(int f, char d) : freq(f), data(d), left(NULL), right(NULL){} }; struct NodeCompare{ bool operator() (const Node* lhs, const Node* rhs) const{ return lhs->freq > rhs->freq; } }; void GetHuffmanCode(Node* node, string code, vector<string>& codes){ if(!node){ return; } if(!node->left && !node->right){ codes[node->data] = code; } GetHuffmanCode(node->left, code + "0", codes); GetHuffmanCode(node->right, code + "1", codes); } vector<string> HuffmanCode(vector<int>& freq, vector<char>& data){ priority_queue<Node*, vector<Node*>, NodeCompare> min_heap; for(int i = 0; i < freq.size(); i++){ min_heap.push(new Node(freq[i], data[i])); } while(min_heap.size() > 1){ Node* left = min_heap.top(); min_heap.pop(); Node* right = min_heap.top(); min_heap.pop(); Node* parent = new Node(left->freq + right->freq, '-'); parent->left = left; parent->right = right; min_heap.push(parent); } vector<string> codes(256, ""); GetHuffmanCode(min_heap.top(), "", codes); return codes; } int main(){ vector<int> freq = {5, 9, 12, 13, 16, 45}; vector<char> data = {'a', 'b', 'c', 'd', 'e', 'f'}; vector<string> codes = HuffmanCode(freq, data); for(int i = 0; i < codes.size(); i++){ if(codes[i] != ""){ cout << i << ": " << codes[i] << endl; } } return 0; } ``` 这个示例程序的输入是一个频率向量和一个数据向量,输出是一个字符串向量,表示每个数据项的哈夫曼编码。这个程序中用到了优先队列(最小堆)来构建哈夫曼编码树,用递归的方式遍历树来获得每个数据项的编码。注意,这个示例程序只是一个简单的实现,可能不够完善,需要根据具体情况进行修改和优化。 希望能够帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

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

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

打赏作者

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

抵扣说明:

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

余额充值