Java经典逻辑编程50题 (转)
2019-07-06 21:17 钱先生 阅读(1413) 评论(0) 编辑 收藏 举报注: 转自https://blog.csdn.net/Alias_fa/article/details/52985112 (摘了题目部分和部分分析,想看原作代码的见原作链接)
【程序1】
題目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
public static void rabbitNO(int month){ /* 題目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 分析: month 1: 1 pair month 2: 1 pair month 3: 2 pair month 4; 3 pair month 5: 5 pair month 6: 8 pair month 7: 13 pair */ /* sum1 = 1 sum2 = 1 sum3 = sum1 + sum2 sum4 = sum2 + sum3 sum5 = sum3 + sum4 sum6 = sum4 + sum5 */ int [] mon = new int[month]; if (month <1){ System.out.println("输入错误."); } else if (month < 3){ System.out.println("第 " + month + "个月有 1 pair."); } else { for (int i = 2; i <month; i++){ mon[0] = mon[1] = 1; mon[i] = mon[i-1] + mon[i-2]; System.out.printf("第 %d 个月有 %d pair.", i+1, mon[i]); } } }
【程序2】 题目:判断101-200之间有多少个素数,并输出所有素数。
public static void nums (){ /** * 需求: 101 到200 之间有多少个素数 * * 分析: * 1. 每一个数除以1到其本身,且余数为0,count !=2, 则不是素数。 * 2. 每个数除以2 得到int j, 如果这个数%i (2<= i <= j)余数为0, 则不是素数. 这样计算量会小一些。下面是以第二处思路写的。 * */ int count = 0; ArrayList al = new ArrayList(); for (int num=101; num<=200; num++){ int j = num/2; for(int i=2; i<=j; i++){ if (num%i==0){ count+=1; } } if (count==0) { al.add(num); } else { count=0; } } System.out.println(al); System.out.println("素数总共有 "+ al.size() + "个."); }
【程序3】 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
public static void narcissus(){ /** * 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。 * * 分析: * a. 把这个数 num 拆解为个位数single, 十位数ten, 百位数hundred. * b. single^3 + ten^3 + hundred^3 = num * c. range : 100 - 999 * */ int single = 0; int ten = 0; int hundred = 0; ArrayList al = new ArrayList(); for (int num = 100; num < 1000; num++){ single = num%10%10; ten = num/10%10; hundred = num/10/10; System.out.println("个: " + single); System.out.println("十: "+ ten); System.out.println("百: "+ hundred); if (Math.pow(single, 3)+ Math.pow(ten, 3) + Math.pow(hundred, 3) == num){ al.add(num); } } System.out.println("共有 "+ al.size() + "个数."); System.out.println(al); }
public static void prime(int num) { /** * 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 ( * 1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。 ( * 2)如果n>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步。 * (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 * * * 分析: * 1. 递归. * a. 给定数字num, int i<=num, num%i==0, 则i是num的因数 * b. 如果把i当作num继续上述操作。 直到得到的因数都是质数为止. * * 2. 递归总是会有重复的质因数被打印出来 。就换了方法。 * a. 另写一个方法判断是否质数 * b. 另写一个方法判断一个数是否另一个数的因数 * c. 循环里只要i同时满足上述两个方法,就加入arraylist, 最后打印arraylist所有值。 * * 注; 若给定的数字本身就是一个质数。直接打印1和这个数就可以了. */ if(isPrime(num)){ System.out.println("1, " + num); } else { ArrayList al = new ArrayList(); for (int i = 1; i <= num / 2; i++) { if (isPrime(i) && isFactor(num, i)) { al.add(i); } } System.out.println(al); } } public static boolean isPrime(int num) { //判断一个数是不是质数 int count = 0; for (int i = 2; i <= num / 2; i++) { if (num % i == 0) { count++; } } if (count > 0) { return false; } else { return true; } } public static boolean isFactor(int a, int b) { //判断是不是因数 if (a % b == 0) { return true; } else { return false; } } }
public static void scores(int sum){ /** * 题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。 * * @para sum * 给出的分数 */ String score = ""; if (sum>=90){ score = "A"; } else if (sum<60){ score = "C"; } else { score = "B"; } System.out.println(score); }
public static void multiple(int m, int n) { /** * 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。 分析:需要了解求最大公约数和最小公倍数的方法 * * 分析: * 最大公约数: * for循环找出m, n的所有公因数,放进arraylist里, 取arraylist.get(arraylist.size()-1) * * 最小公倍数 * a*b/最大公约数 * * 看人家写的MaxcommonDivisor方法,几行代码就出来了。而且计算量小的多,也没有那么多判断. * * */ int j = m / 2; int k = n / 2; ArrayList<Integer> al = new ArrayList<Integer>(); if (isFactor(m,n)| isFactor(n,m)){ //如果m,n其中一个数是另一个数的倍数 System.out.println("最大公约数是: " + Math.min(m,n)); System.out.println("最小公倍数是: " + Math.max(m,n)); } else { for(int i=2; i<=Math.max(j,k); i++){ if (m%i==0 && n%i==0){ al.add(i); } } if (al.size()==0){ //如果m,n没有1以外的公约数 System.out.println("最大公约数是: 1" ); System.out.println("最小公倍数是: " + Math.multiplyExact(m,n)); } else if (al.size()==1){ //如果m,n除了1以外只有一个公约数 System.out.println("最大公约数是: " + al.get(0) ); System.out.println("最小公倍数是: " + m*n/al.get(0)); } else { System.out.println("最大公约数是: " + al.get(al.size()-1) ); System.out.println("最小公倍数是: " + m*n/al.get(al.size()-1)); } } } public static boolean isPrime(int num) { //判断一个数是不是质数 int count = 0; for (int i = 2; i <= num / 2; i++) { if (num % i == 0) { count++; } } if (count > 0) { return false; } else { return true; } } public static boolean isFactor(int a, int b) { //判断是不是因数 if (a % b == 0) { return true; } else { return false; } }
public static void countNo(String str){ /** * 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。 分析:这题也比较简单,知道怎么表示字母、空格、数字就OK * * */ int letter=0; int num=0; int space=0; int other=0; char [] al = str.toCharArray(); for(int i=0; i<=al.length-1; i++){ char temp = al[i]; if(('a'<=temp && temp<='z')|('A'<=temp && temp<='Z') ){ letter++; } else if (48 <= temp && temp <= 57) { num++; } else if (temp==' '){ space++; } else { other++; } } System.out.println("字母共有: " + letter + " 个。"); System.out.println("数字共有: " +num + " 个。"); System.out.println("空格共有: " +space + " 个。"); System.out.println("其它字符共有: " +other + " 个。"); }
public static void addNums(int a, int b){ /** * 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。 * * @para a * 基础数字,即题目中的a * * @param b * 待求和的数字个数,i.e.等式右边的最后一个数有几位数. */ ArrayList<String> arr = new ArrayList(); int sum=0; for(int i=0; i<b; i++){ String temp = ""; String[] str = new String[i+1]; for(int j=0; j<str.length; j++){ str[j] = a+""; } temp = StringUtils.join(str); arr.add(temp); } for(int k=0; k<arr.size();k++){ int num = Integer.valueOf(arr.get(k)); sum+=num; } System.out.println(sum); }
public static void perfectNo (){ /** * 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程 找出1000以内的所有完数。 分析:跟求一个数的素因数有类似的地方,但这里的因子可以不是素数 */ for (int i=1; i<1000; i++){ int sum=0; for(int j=1; j<=i/2; j++){ if (i%j==0){ sum+=j; } } if(sum==i){ System.out.println(i); } } }
public static void ball(){ /** * 【程序10】 题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高? */ Float high = Float.parseFloat("100"); Float bounce = 0F; Float sum = 0F; for (int i=1; i<11; i++){ bounce = (float)(high/(Math.pow(2,i))); Float temp = bounce*2; Float distance = temp+bounce; sum+=distance; } System.out.println("第10次反弹的高度是: " + bounce); System.out.println("共反弹距离: " + sum); }
【程序11】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
【程序12】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分 按10%提成,高于10万元的部分,可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部 分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当 月利润I,求应发放奖金总数? 【程序13】 题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
public static void dayInYear() { /** * 【程序14】 题目:输入某年某月某日,判断这一天是这一年的第几天? */ Date date = new Date(2019, 2, 1); Calendar ca = Calendar.getInstance(); ca.setTime(date); System.out.println(ca.get(Calendar.DAY_OF_YEAR)); }
public static void sortNum(int x, int y, int z){ /** * 【程序15】 题目:输入三个整数x,y,z,请把这三个数由小到大输出 */ int [] arr = new int[]{x,y,z}; for(int i=0; i<arr.length-1; i++){ for(int j=0; j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){ swap(arr, j, j+1); } } } for(int i=0; i<arr.length; i++){ System.out.println(arr[i]); } } public static void swap(int[] arr, int i, int j){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
public static void multipleTrick(){ /** * 【程序16】 题目:输出9*9口诀。 */ for(int i=1; i<10; i++){ for(int k=1; k<10; k++){ System.out.print(i+"*" + k + "=" + i*k + " "); } System.out.println("\r\n"); } }
public static void fraction(){ /** * 【程序20】 题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。 */ int num1 = 2; int num2 = 1; int[] list1 = new int[20]; int[] list2 = new int[20]; list1[0] = num1; list2[0] = num2; list1[1] = list1[0] + list2[0]; list2[1] = list1[0]; for(int i=2; i<20; i++){ list1[i] = list1[i-1]+list2[i-1]; list2[i] = list1[i-1]; } BigDecimal sum = new BigDecimal(0); for (int i=0; i<list1.length; i++) { BigDecimal temp = new BigDecimal(list1[i]).divide(new BigDecimal(list2[i]),5,ROUND_HALF_UP); System.out.println("第 " + i + " 个数是: " + temp); sum=sum.add(temp); } System.out.println(sum); }
【程序23】 题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,
又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大? 分析:这题与程序17有异曲同工之妙,倒过来分析就简单了。(代码略)
【程序24】 题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
分析:又是拆数字游戏
public static void main(String[] args){ revertNum(-3928); } public static void revertNum(int num){ String str = (num+"").replace("-","").replace("+",""); System.out.println("num是 " + str.length() + " 位数"); String revertNo = new StringBuilder().append(str).reverse().toString(); int result; if(num>0){ result = Integer.parseInt(revertNo); System.out.println("反转后的数字是: " + result); } else { result = 0-Integer.parseInt(revertNo); System.out.println("反转后的数字是: " + result); } }
【程序25】 题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
分析:能把一个数的各个位上的数拆出来就简单了。参考程序3(代码略)
public static void main(String[] args){ System.out.println( palindrome(212)); } public static boolean palindrome(int num){ /* 【程序25】 题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。 */ String str = num+""; String temp = new StringBuilder().append(str).reverse().toString(); if(str.equals(temp)){ return true; } return false; }
【程序26】 题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母。 分析:你首先要知道星期一到星期天的英文单词,然后就是用 switch 了
public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(5); list.add(7); for(int i=11; i<101; i++){ if(i%2!=0 && i%3!=0 && i%5!=0 && i%7!=0 ){ list.add(i); } } System.out.println(list); }
【程序28】 题目:对10个数进行排序 分析:有多种方法,参考java里的4种排序算法
public static void sortNum(int[] arr){ Arrays.sort(arr); for(int num:arr){ System.out.println(num); }
【程序29】 题目:求一个3*3矩阵对角线元素之和 分析:用二维数组,难度不大
【程序30】 题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。 分析:类似插入排序,也还有其他方法
public static int[] insertNum(int[] arr, int num){ int[] result = Arrays.copyOf(arr,arr.length+1); result[result.length-1]= num; Arrays.sort(result); for (int nu:result) { System.out.println(nu); } //如果不需要打印出数组,可以把for循环去掉. return result; }
【程序31】 题目:将一个数组逆序输出。 分析:输出数组时从大下标开始就可以了
public static int[] revertArray(int[] arr){ int[] result = new int[arr.length]; for(int i=arr.length-1;i>=0;i--){ result[result.length-1-i]=arr[i]; } for (int num:result ) { System.out.println(num); } return result; }
【程序32】 题目:取一个整数a从右端开始的4~7位。 分析:如果可以把这个整数转换为一个字符串就好解决了
【程序33】 题目:打印出杨辉三角形(要求打印出10行如下图) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
【程序35】 题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
【程序36】 题目:有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数
【程序37】 题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
【程序38】 题目:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。
【程序39】 题目:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数)
【程序40】 题目:字符串排序。
分析:主要是字符串的比较,第一个相同,比第二个......(原来数组中有 sort 方法)
【程序41】 题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。
第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,
问海滩上原来最少有多少个桃子?
【程序42】 题目:809*??=800*??+9*??+1 其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
分析:两位数就是10—99。。。。。经过自己验证,题目右边的 + 1 去掉才有答案。原题无解,可能题目传着传着就传错了
【程序43】 题目:求0—7所能组成的奇数个数。
分析:我认为这个题目没说明白,我觉得题目的意思应该是每个数字只出现一次吧。如果每个数字都可以出现多次,又没限制最多能有几位数,
那么这个奇数岂不是可以有无限个。
我也看了很多网友的答案,他们绝大部分人都认为每个数可以出现多次,而且这个数最大就是 77777777,只能有 8 位。
既然每个数可以重复,那么这个数为什么不能超过 8 位,题目上没说啊。不知道你们是怎么理解的,难道是为理解错了?
不过我还是看到一个网友跟我的理解是一样的,他的实现方法我觉得很不错,参考过来,代码如下,已被我稍微优化。
【程序44】
题目:一个偶数总能表示为两个素数之和。
分析:素数,又是素数,这题不难了吧
【程序45】 题目:判断一个素数能被几个9整除
分析:题目是什么意思。素数就是不能被1和自己以外的任何数整除,而几个9组成的数必然能被9整除,所以一定不是素数,题目好像有问题。
【程序46】 题目:两个字符串连接程序
分析:用 “+”号不就行了么。(代码略)
【程序47】 题目:读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的*。
分析:主要是用到 Random
【程序48】 题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用
和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。 分析:又是拆数字,每位数字加上 5 的和除以 10 的余数替换该数
【程序49】 题目:计算字符串中子串出现的次数
分析:这里是要用正则表达式么
【程序50】 题目:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,
况原有的数据和计算出的平均分数存放在磁盘文件"stud"中。
分析:数据要怎么输出到文件