Day19

本文探讨了外部排序的过程,包括预处理和合并排序阶段,以及如何通过归并策略处理大文件排序。此外,提到了堆和队列的数据结构特点,以及局部变量在递归控制中的作用。还介绍了一个关于汽水瓶兑换的问题,展示了如何通过数学方法解决实际问题。最后,文章涉及了字符串处理,特别是寻找两个字符串的最长公共子串的方法。
摘要由CSDN通过智能技术生成

外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。一般用归并排序, 空间复杂度是O(n). 一般来说外排序分为两个步骤:预处理和合并排序。首先,根据可用内存的大小,将外存上含有n个纪录的文件分成若干长度为t的子文件(或段);其次,利用内部排序的方法,对每个子文件的t个纪录进行内部排序。这些经过排序的子文件(段)通常称为顺串(run),顺串生成后即将其写入外存。这样在外存上就得到了m个顺串(m=[n/t])。最后,对这些顺串进行归并,使顺串的长度逐渐增大,直到所有的待排序的几率成为一个顺串为止。

 

 

根据完全二叉树的性质,满二叉树和完全二叉树可以按层序进行顺序存储,但一般的二叉树不适用。堆可以用一维数组来存储也可以用完全二叉树来直观地表示堆的结构。队列、栈本身就是顺序存储的

 

 

局部变量 只是在调用局部范围有效,出了这次调用的范围就无效了,它不能控制递归的结束。

如果没有一个分支不调用自身,递归就不会结束。

使用全局变量或使用一个或多个参数的确可以控制递归的结束,但题目中指出了"一定"。答案是并不是只有这两种方式。 

 

 

 

 链表的特点就是不一定按照顺序存储,无论是存储的空间位置还是存储的顺序都是任意的。

某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。

小张手上有n个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。

数据范围:输入的正整数满足 1≤n≤100 1 \le n \le 100 \ 1≤n≤100 

注意:本题存在多组输入。输入的 0 表示输入结束,并不用输出结果。

 

输入描述:

输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。

输出描述:

对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。

示例1

输入

3
10
81
0

输出

1
5
40

说明

样例 1 解释:用三个空瓶换一瓶汽水,剩一个空瓶无法继续交换
样例 2 解释:用九个空瓶换三瓶汽水,剩四个空瓶再用三个空瓶换一瓶汽水,剩两个空瓶,向老板借一个空瓶再用三个空瓶换一瓶汽水喝完得一个空瓶还给老板  
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            //如果输入为0  表示输入结束
            if(n==0){
                break;
            }
            //如果输入为0 则没有输出
            System.out.println(drink(n));
        }
    }

    /**
     * 输入大于等于3的n个汽水瓶子,最多可以喝几瓶水
     *
     * @param n
     * @return
     */
    private static int drink(int n) {
        //ret记录结果值
        int ret=0;
        //如果剩两瓶 可以向老板借一瓶,如果剩一瓶则不能
        //n是瓶子数
        //能换到cur瓶饮料
        int cur=1;
        while (cur>0){
            if(n==1){
                break;
            }
            if(n==2){
                ret++;
                break;
            }
            cur=n/3;
            ret+=cur;
            n=cur+n%3;
        }
        return ret;
    }
}

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。

注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

数据范围:字符串长度1≤length≤300 1\le length \le300 \ 1≤length≤300 

进阶:时间复杂度:O(n3) O(n^3)\ O(n3) ,空间复杂度:O(n) O(n)\ O(n) 

 

输入描述:

输入两个字符串

输出描述:

返回重复出现的字符

示例1

输入

abcdefghijklmnop
abcsafjklmnopqrstuvw

输出

jklmnop
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str1 = scanner.nextLine();
        String str2 = scanner.nextLine();
        String s = publicStr(str1, str2);
        System.out.println(s);
    }

    /**
     * 输入两个字符串,查找两个字符串的最长公共子串
     *
     * @param str1
     * @param str2
     * @return
     */
    private static String publicStr(String str1, String str2) {
        //记录结果字符串
        String ret = "";
        //记录新的公共字串 与结果字符串比较
        String newRet = "";
        //在两个字符串做四个引用
        if(str2.length()<str1.length()){
            String str=str2;
            str2=str1;
            str1=str;
        }
        if(str2.contains(str1)){
            ret=str1.substring(0,str2.length()-1);
            return ret;
        }

        for (int i = 0; i < str1.length(); i++) {
            for (int j = str1.length(); j >=i; j--) {
                if(str2.contains(str1.substring(i,j))){
                    newRet=str1.substring(i,j);
                    ret=ret.length()>=newRet.length()?ret:newRet;
                }
            }
        }
        return ret;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值