算法练习-Java

Java算法练习

先来一些基础的算法

九九乘法表

// 九九乘法表

class  day01
{
	public static void main(String[] args) 
	{
		for(int i = 1;i<=9;i++){
			for(int j = 1;j<=i;j++){
				System.out.print(i+"*"+j+"="+i*j+" ");
			}
		System.out.println("\n");
		}

	}
}

鸡兔同笼

//鸡兔同笼

import java.util.Scanner;

class  day01
{
	public static void main(String[] args) 
	{
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入脚的数量:");
		int foot = sc.nextInt();
		System.out.print("请输入头的数量:");
		int sum = sc.nextInt();

		int chicken = 1;
		int rabbit = sum - chicken;
		while(true){
			if(rabbit * 4 + chicken * 2 == foot){
				System.out.println("有" + chicken +"只鸡");
                System.out.println("有" + rabbit + "只兔子");
				break;  //这个break很关键
			}
			else{
				chicken ++;	
				rabbit --;
				if (rabbit < 0) {
                    System.out.println("这头和脚数量不匹配啊宝子");
                    break;
				}
			}
		}

	}
}

冒泡排序

//冒泡排序
public class demo_sort {
    public static void main(String[] args) {
        //冒泡排序算法
        int[] numbers=new int[]{1,5,8,2,3,9,4};
        //需进行length-1次冒泡
        for(int i=0;i<numbers.length-1;i++)
        {
            for(int j=0;j<numbers.length-1-i;j++)
            {
                if(numbers[j]>numbers[j+1])
                {
                    int temp=numbers[j];
                    numbers[j]=numbers[j+1];
                    numbers[j+1]=temp;
                }
            }
        }
        System.out.println("从小到大排序后的结果是:");
        for(int i=0;i<numbers.length;i++)
            System.out.print(numbers[i]+" ");
    }
}

选择排序

//选择排序
public class SelectSort {
    
    public static void selectSort(int[] arr) {
        if(arr == null || arr.length == 0)
            return ;
        int minIndex = 0;
        for(int i=0; i<arr.length-1; i++) { //只需要比较n-1次
            minIndex = i;
            for(int j=i+1; j<arr.length; j++) { //从i+1开始比较,因为minIndex默认为i了,i就没必要比了。
                if(arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            
            if(minIndex != i) { //如果minIndex不为i,说明找到了更小的值,交换之。
                swap(arr, i, minIndex);
            }
        }
        
    }
    
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
 
}

做一些PTA上面的题 先做做乙类:

卡拉兹(Callatz)猜想

/*001
卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。对给定的任一不超过 1000 的正整数 n需要多少步才能得到 n=1?
*/
import java.util.Scanner;

public class day{
public static void main(String []args){
        System.out.println("输入正整数:");
        Scanner s=new Scanner(System.in);
        int n = s.nextInt();
		int m = 0;
        while(n!=1){
			m++;
        if(n%2!=0){
            n = (3*n+1)/2;
        }else{
            n = n/2;
        }
        }
        System.out.println(m);
        
    }
    
}

写出这个数

/*002
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
*/
import java.util.Scanner;

public class day{
public static void main(String []args){
	int sum = 0;
	char[] n = new char[101];
        System.out.println("输入正整数:");
        Scanner scanner=new Scanner(System.in);
        String s = scanner.nextLine();
		for (int i = 0; i < s.length(); i++) {
			n[i] = s.charAt(i);
		}
		int i = 0, j = 0;
		int[] b = new int[11];
		while (n[i] != '\0') {
			sum += n[i] - '0';
			i++;
		}

		if (sum == 0) {
			letter(0);
		} else {
			while (sum != 0) {
				b[j] = sum % 10;
				sum /= 10;
				j++;
			}
			for (i = j - 1; i > 0; --i) {
				letter(b[i]);
				System.out.print(" ");
			}
		}

		letter(b[0]);
	}

	public static void letter(int l) {
		switch (l) {
		case 0:
			System.out.print("ling");
			break;
		case 1:
			System.out.print("yi");
			break;
		case 2:
			System.out.print("er");
			break;
		case 3:
			System.out.print("san");
			break;
		case 4:
			System.out.print("si");
			break;
		case 5:
			System.out.print("wu");
			break;
		case 6:
			System.out.print("liu");
			break;
		case 7:
			System.out.print("qi");
			break;
		case 8:
			System.out.print("ba");
			break;
		case 9:
			System.out.print("jiu");
			break;
		}
	}
}

java中字符串中子字符串查找共有四种方法如下:
1、int indexOf(string str) :返回第一次出现的指定子字符串在此字符串中的索引,如果没有找到该字符串则返回-1。
2、int indexOf(string str, int startIndex) : 从指定的索引处开始,返回第一次出现的指定子字符串在此字符串中的索引,如果没有找到该字符串则返回-1。
3、int lastIndesOf(String str) : 返回在此字符串中最右边出现指定子字符串的索引,如果没有找到该字符串则返回-1。
4、int lastIndexOf(string str,int startIndex) :从指定的索引处开始向后索引,返回在此字符串中最后一次出现的指定子字符串的索引,如果没有找到该字符串则返回-1。

我要通过

/*003
题目:1003 我要通过! (20分)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

思路
盲点
题目中的条件2:任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
左右两个x代表相同的字符串,比如左边是两个A,右边也得是两个A
*/
import java.util.Scanner;

public class test {
    public static void main(String []args){
        Scanner sc = new Scanner(System.in);
        int i = sc.nextInt();
        while (i-- > 0){
            String s = sc.next();
            if(judge(s)){
                System.out.println("YES");
            }else {
                System.out.println("NO");
            }
        }
        sc.close();

    }

    //本题必须满足的条件如下:
    // 1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
    // 2.P和T之间不能没有A(A的个数大于等于1,等于0就是错的)
    // 3.开头(P之前)的A的个数 * 中间(P和T中间)的A的个数 = 结尾(T之后)的A的个数,
    // 4.P和T只能有一个(可以合并到条件4,判断了条件4就不要判断这个了,看了条件4的计算公式就全明白了
    //      比如PPATT,P_index*(T_index - P_index - 1) == str.length() - T_index - 1)->  0*()==5-3-1

    public static boolean judge(String str){
        String newStr = str.replace("P", "").replace("A", "").replace("T", "");
        if (newStr.isEmpty()) {//判断条件1
            int P_index = str.indexOf('P');
            int T_index = str.indexOf('T');
            if (P_index == T_index - 1) {//判断条件2
                return false;
            }
            return P_index * (T_index - P_index - 1) == str.length() - T_index - 1; //判断条件3
        }
        return false;
    }

}

成绩排名

/*004
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:
每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
  ... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩
*/
import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number = scanner.nextInt(); //键盘输入获取学生个数
        int max = 0, min = 100;   //设置最高分和最低分的初始值
        String maxInfo = "", minInfo = "";
        //nextLine()读取了上一次输入nextInt()留下的“\n”,所以没有给用户输入(软件认为用户输了一个”\n”),而是直接换行了
        scanner.nextLine();//消除换行符影响,提前吞掉空格,防止后面吞掉
        while (number > 0) {
            //使用split()方法将输入的字符串以空格为间隔符将字符串分成字符数组
            String[] str = scanner.nextLine().split(" ");
            //str[2]中存取的是分数字符,转换为整型
            int score = Integer.parseInt(str[2]);
            String info = str[0] + " " + str[1];//将姓名和学号合并一个字符串
            //比较分数,交换分数以及字符串信息
            if (score > max) {
                max = score;
                maxInfo = info;
            }
            if (score < min) {
                min = score;
                minInfo = info;
            }
            number--;
        }
        //输出结果
        System.out.println(maxInfo);
        System.out.println(minInfo);
    }
}

换个格式输出整数

/*005
让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。
*/
import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        System.out.print("请输入一个小于1000的正整数:");
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        for (int i = 0; i < n / 100; i++) {
            System.out.print("B");
        }
        for (int i = 0; i < n /10 % 10; i++) {
            System.out.print("S");
        }
        for (int i = 0; i < n % 10; i++) {
            System.out.print(i+1);
        }
    }
}

素数对猜想

/*006

*/
import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        sc.close();
        int first_prime = 2;
        int count = 0;
        for (int i = 3; i <= N; i++) {
            int j;
            int temp = (int) Math.sqrt(i);
            for (j = 2; j <= temp; j++) {
                if (i % j == 0) {
                    break;
                }
            }
            if (j == (temp + 1)) {
//                System.out.println(i);
                if ((i - first_prime) == 2) {
                    count++;
                }
                first_prime = i;
            }
        }
        System.out.println(count);
    }
}

数组元素循环右移问题

/*007
一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
*/
import java.util.Scanner;
public class test
{
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("整数数量为:");
        int n=sc.nextInt();
        System.out.println("右移位数为:");
        int m=sc.nextInt();
        System.out.println("依次输入"+n+"个整数:");
        int arr[]=new int[2*n];
        //将数据存2份
        for(int i=0;i<n;i++)
        {
            arr[i]=arr[i+n]=sc.nextInt();
        }
        m=m%n; //获得移动位数
        //打印
        System.out.println("右移"+m+"位后依次为:");
        for(int i=0;i<n;i++)
        {
            System.out.print(arr[n-m+i]);
            if(i==n-1)
            {
                break;
            }
            System.out.print(" ");
        }
    }
}

说反话

一、StringBuilder对象的创建
1.常规创建

StringBuilder builder = new StringBuilder();

2.在创建的时候添加初始字符串

StringBuilder builder = new StringBuilder("abc");

3.在创建的时候添加初始长度

StringBuilder builder = new StringBuilder(初始长度);

这里需要注意的是如果在StringBuilder的对象创建时没有指定长度,StringBuilder对象会自动生成一个16位的字符数组
二、StringBuilder对象的方法
1.builder.append()
作用:追加数据

builder.append("just");

在加入新字符串时,不会在内存中新开辟字符串空间,只是给原有的字符串尾部加入新字符串

2.builder.insert()
作用:向指定位置插入数据

builder.insert(0, "you");

每次加入新字符串之后都会改变字符串中每个字符的地址,插入后原始指定位置的数据向后移

3.builder.deleteCharAt()
作用:删除指定位置的数据

builder.deleteCharAt(index);

4.builder.delete( )
作用:删除指定范围的数据左闭右开

builder.delete(beginIndex, endIndex);

范围:从开始位置到结束位置的前一个

5.builder.toString()
作用:将对象中的数据以字符串的形式返回

builder.toString();

6.builder.reverse()
作用:将bulider中的数据反转

builder.reverse();
/*008
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
*/
import java.util.Scanner;

public class test
{
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入内容:");
        String[] first = sc.nextLine().split(" ");
        StringBuilder build = new StringBuilder();
        for (int i = first.length-1;i >= 0;i--){
            build.append(first[i]+" ");
        }
        System.out.println("倒序后的句子为:"+build.toString().trim());
    }
}

一元多项式求导

/*009
设计函数求一元多项式的导数。
*/
import java.util.ArrayList;
import java.util.Scanner;

public class test
{
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入内容:");
        String str = sc.nextLine();  //不知道具体的输入个数 先输入字符串
        String []n = str.split(" ");
        ArrayList<Integer> a = new ArrayList<>();

        for(int i = 0;i<n.length;i+=2){
            if (n.length == 2&&Integer.parseInt(n[1])==0){
                System.out.println("0 0");
            }
            if (Integer.parseInt(n[i+1])==0){           //若多次项只剩常数结束循环
                break;
            }
            int b = Integer.parseInt(n[i])*Integer.parseInt(n[i+1]);
            int c=Integer.parseInt(n[i+1])-1;
            a.add(b);                                     //添加进列表
            a.add(c);
        }

        for (int j:a){                                      //循环输出
            if (j!=0){                                      //最后一个数后不加空格
                System.out.print(j+" ");
            }else {
                System.out.print(j);
            }
        }


    }
}

A+B 和 C

/*010
给定 3 个整数 A、B 和 C,请判断 A+B 是否大于 C。
*/
import java.util.Scanner;

public class test {
    // 思路:输入后直接判断即可,需要注意的是:int的范围是[-2^31 ~ 2^31-1],所以两个数相加会溢出,需要使用long
    public static void main(String[] args) {
        long a, b, c;
        Scanner s = new Scanner(System.in);
        System.out.print("请输入要比较的组数:");
        int t = s.nextInt();
        for (int i = 0; i < t; i++) {
            System.out.print("请依次输入要比较的3个数:");
            a = s.nextLong();
            b = s.nextLong();
            c = s.nextLong();
            if (a+b > c) {
                System.out.println("Case #"+(i+1)+": true");
            } else {
                System.out.println("Case #"+(i+1)+": false");
            }
        }
    }
}

数素数

/*
现任给两个正整数 M≤N
 ,请输出M到N的所有素数。
*/
package com.hbut.pat;
import java.util.Scanner;

public class test{
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in);
    int left = sc.nextInt();
    int right = sc.nextInt();
    int times = 0;
    for(int i=1 ; ;i++){
        if(isPrimeNum(i)){
            times++;
            if(times>=left&times<=right){
                if((times-left+1)%10==0||times-left==right-left){
                    System.out.println(i);
                }else{
                    System.out.printf("%d ", i);
                }
            }
            if(times == right){
                break;
            }
        }
    }
  }

  public static boolean isPrimeNum(int a){
      if(a==1){
          return false;
      }
      if(a%2==0&&a!=2){
        return false;
      }
      for(int i=3;i<=Math.sqrt(a);i+=2){
          if(a%i==0){
              return false;
          } 
      }
    return true;
  }
}

做做甲类:

1001 A+B Format

Calculate a+b and output the sum in standard format – that is, the digits must be separated into groups of three by commas (unless there are less than four digits).

//这种格式化的方法极其简单
import java.util.Scanner;

public class day{
        public static void main(String[] args){
            Scanner sc=new Scanner(System.in);
            int a = sc.nextInt();
            int b = sc.nextInt();
            System.out.printf("%,d", a+b);//表示加逗号格式化输出整数
        }
	}

这里用到了Java的一个很强大的输出函数:System.out.printf( );
基本格式:格式控制符以一个%开始,一个字母结束,字母规定了方法按照何种方式打印这个值,例如d表示十进制整数(int),f表示浮点数(double).
eg:System.out.printf(“%,08d”, a+b);
表示输出8位整数a+b每三位以逗号隔开,不够8位的补零(要注意的是8位是算逗号位和符号位的)

1002 A+B for Polynomials

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

public class day {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Double[] A = new Double[1001];
        for (int i = 0; i < 1001; i++) { //防止 C[i] = A[i] + B[i];发生空指针异常
            A[i] = 0.0;
        }
        Double[] B = new Double[1001];
        for (int i = 0; i < 1001; i++) {//防止 C[i] = A[i] + B[i];发生空指针异常
            B[i] = 0.0;
        }

        int K = sc.nextInt();
        int index;
        while (K != 0) {
            index = sc.nextInt(); //指数
            A[index] = sc.nextDouble(); //系数
            K--;
        }


        K = sc.nextInt();
        while (K != 0) {
            index = sc.nextInt(); //指数
            B[index] = sc.nextDouble(); //系数
            K--;
        }
        sc.close();


        double[] C = new double[1001];
        int count = 0;
     
        for (int i = 0; i < 1001; i++) {
            C[i] = A[i] + B[i];
            if ((A[i] != 0 || B[i] != 0) && C[i] != 0) {
                // 这得小心一种情况。输入的两行分别是 a:1 1 1  b:1 1 -1。
                // A[1]+B[1]=0,这时count不应该再加
                count++;
            }
        }

        System.out.print(count);
        //从大到小输出
        for (int i = 1000; i >= 0; i--) {
            if (C[i] != 0) {
                System.out.print(" " + i + " ");
                System.out.printf("%.1f", C[i]);
            }
        }
    }
}

转向LeetCode练习

  • 子串问题:考虑滑动窗口;

滑动窗口: 其实就是一个队列,比如: abcabcbb要求从中找出不能有相同字符的最长字符串,则依次进队,进入到 abc时 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列,只要把队列的左边不满足条件的元素移出,直到满足题目要求。即把abc移出。

//使用方法
 HashMap<Character, Integer> map = new HashMap<Character, Integer>();

补: hashmap里有很多针对散列表的方法

  • 涉及出现次数,需要用到散列表(hash表);

哈希表是根据关键码值(Key value)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值