赞
踩
该题目指定用单个字符来进行日期的判断,而单个字符是可以当int型使用的,所以在此处用switch…case较为方便,示例代码如下:
private static String judgeWeek(char[] weeks){ String week=""; switch(weeks[0]){ case 'M': case 'm': week="Monday"; break; case 'T': case 't': if(weeks[1]=='u'||weeks[1]=='U') week="Tuesday"; else if(weeks[1]=='h'||weeks[1]=='H') week="Thursday"; break; case 'W': case 'w': week="Wednesday"; break; case 'F': case 'f': week="Friday"; break; case 'S': case 's': if(weeks[1]=='a'||weeks[1]=='A') week="Saturday"; else if(weeks[1]=='s'||weeks[1]=='U') week="Sunday"; break; } return week; }
该题目的逻辑并不复杂,之前的题目中也有类似的,双层for循环,外层被除数,内层除数,遍历相除,输出筛选出来的值即可。此处说一下可能会采的坑。初版代码如下:
private static void printNum(int num){
boolean isPrint=true;
for(int i=3;i<num;i++){
for(int j=2;j<=(int)Math.sqrt(i);j++){
if(i%j==0){
isPrint=false;
break;
}
}
if(isPrint)
System.out.println(i);
}
}
该代码粗看,好像没什么问题,但运行一下,发现输出的值只有一个"3"。这明显是不对的。细看才发现,该代码中有个问题:isPrint变量被赋值一次false后,就一直是false,导致后续不会再输出素数。所以需要将代码改一版:
private static void printNum(int num){
boolean isPrint=true;
for(int i=3;i<num;i++){
for(int j=2;j<=(int)Math.sqrt(i);j++){
if(i%j==0){
isPrint=false;
break;
}else{
isPrint=true;
}
}
if(isPrint)
System.out.println(i);
}
}
这版代码加入了每次循环时对isPrint变量的重新赋值,运行结果也是正确的。但是还不是最优的,外层for循环选取的初始值是3,是个奇数,这是个伏笔,每次不用自增1,自增2就行,因为偶数肯定不是素数,这样,循环次数就会减少一半。示例代码如下:
private static void printNum(int num){
boolean isPrint=true;
for(int i=3;i<num;i=i+2){
for(int j=2;j<=(int)Math.sqrt(i);j++){
if(i%j==0){
isPrint=false;
break;
}else{
isPrint=true;
}
}
if(isPrint)
System.out.println(i);
}
}
关于各种常用的排序算法,在《算法》分类中有详细的介绍,此处以冒泡排序来简单说下排序。冒泡排序的步骤是比较固定的:
1>比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2>每趟从第一对相邻元素开始,对每一对相邻元素作同样的工作,直到最后一对。
3>针对所有的元素重复以上的步骤,除了已排序过的元素(每趟排序后的最后一个元素),直到没有任何一对数字需要比较。
具体落实到代码上,也是需要两层for循环,一个表示要比较的数中前面的那个,一个表示后面的那个。每次比较,都会将序列汇总的一个最值放到末端,进行n-1趟比较、移动即可完成排序过程。示例代码如下:
private static void sort(int[] array){
/*外循环为排序趟数,array.length个数进行array.length-1趟 */
for(int i=0;i<array.length-1;i++){
/*内循环为每趟比较的次数,第i趟比较array.length-i次 */
for(int j=0;j<array.length-1-i;j++){
/*相邻元素比较,若满足条件则交换(升序为左大于右,降序反之) */
if(array[j]>array[j+1]){
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
}
矩阵的叫法显得有些高级,此处可以理解为求一个二维数组的对角线元素之和。对于该题,把从左上角到右下角和从左下角到右上角的原色累加一下就行,落实到代码依然是双层for循环。本题难的是如何挑选出两列元素。规则有两个(二维数组的行列下标分别为i、j):
1>i == j,挑选出来的从左上角到右下角的元素。
2>i == (array[0].length-j-1),挑选出来的是左下角到右上角的元素。
示例代码如下:
private static int sum(int[][] array){
int sum=0;
for(int i=0;i<array.length;i++){
for(int j=0;j<array[0].length;j++){
/*此处有两个判断条件:
* 1、i==j,挑选出来的从左上角到右下角的元素
* 2、i==(array[0].length-j-1),挑选出来的是左下角到右上角的元素
* 两者会挑选出重复的元素,但是用的是||运算,该元素智慧选取一次*/
if((i==j) || (i==(array[0].length-j-1)))
sum=sum+array[i][j];
}
}
return sum;
}
该题目的逻辑还是比较复杂的,可以通过下面的步骤来进行:
1>判断是升序还是降序,因为不同序列的最大值和最小值在不同的位置。
2>判断是不是可以直接插在首部或尾部。如果可以插入首部,所有元素往后移一位;如果可以插在尾部,在新的数组中拷贝原数组的所有元素,然后在最后一位插入新元素即可。
3>如果要在中间位置插入,就要遍历,寻找要插入的位置,然后先拷贝插入位置之前的元素,再插入新元素,再拷贝插入位置之后的元素。
示例代码如下:
private static int[] insert(int[] array,int num){ int[] newArray=new int[array.length+1]; /*默认升序*/ boolean isSscending=true; /*假如第一个元素大于最后一个元素,为降序,此处不考虑整个序列中元素都相等的极端情况*/ if(array[0]>array[array.length-1]){ isSscending=false; } /*升序数组*/ if(isSscending){ /*要插入的元素小于等于最小值,插入到首部*/ if(num<=array[0]){ System.arraycopy(array, 0, newArray, 1, array.length); newArray[0]=num; /*要插入的元素大于等于最大值,插入到尾部*/ }else if(num>=array[array.length-1]){ System.arraycopy(array, 0, newArray, 0, array.length); newArray[newArray.length-1]=num; }else{ int insertPosition=0; /*寻找要插入的位置*/ for(int i=0;i<array.length;i++){ if(num<array[i]){ insertPosition=i; break; } } System.out.println("insertPosition:"+insertPosition); /*拷贝插入位置前的元素*/ System.arraycopy(array, 0, newArray, 0, insertPosition); /*插入新元素*/ newArray[insertPosition]=num; /*拷贝插入位置后的元素*/ System.arraycopy(array, insertPosition, newArray, insertPosition+1,array.length-insertPosition); } /*降序数组*/ }else{ /*要插入的元素小于等于最小值,插入到末尾*/ if(num<=array[array.length-1]){ System.arraycopy(array, 0, newArray, 0, array.length); newArray[newArray.length-1]=num; /*要插入的元素大于等于最大值,插入到首部*/ }else if(num>=array[0]){ System.arraycopy(array, 0, newArray, 1, array.length); newArray[0]=num; }else{ int insertPosition=0; /*寻找要插入的位置*/ for(int i=0;i<array.length;i++){ if(num>array[i]){ insertPosition=i; break; } } System.out.println("insertPosition:"+insertPosition); /*拷贝插入位置前的元素*/ System.arraycopy(array, 0, newArray, 0, insertPosition); /*插入新元素*/ newArray[insertPosition]=num; /*拷贝插入位置后的元素*/ System.arraycopy(array, insertPosition, newArray, insertPosition+1,array.length-insertPosition); } } return newArray; }
这个题考对数组下标的使用,在每次的for循环中,怎么拿到和循环次数i相反位置的元素。示例代码如下:
private static void print(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.println(arr[arr.length-1-i]);
}
for(int i=arr.length-1;i>=0;i--){
System.out.println(arr[i]);
}
}
因为不知道这个数字有多少位,如果用数字的运算符来计算的话,可能实现难度稍大,可以还采用之前简单的转换为char数组的方式来实现。示例代码如下:
private static void printFour(int num){
char[] chars=String.valueOf(num).toCharArray();
for(int i=0;i<4;i++){
System.out.print(chars[chars.length-1-i]+" ");
}
}
该题目和之前的输出菱形*的题有些相似,增加的难度在于要计算输出的非空格元素的值,所以此题哟分为两步:先计算,再输出,步骤如下:
1>先计算山坡两边,也就是山表面值的值,都是1,然后再计算山里面元素的值,该位置的值都等于上层两个相邻元素之和。
2>输出元素,其实创建了一个[10][10]的数组之后,我们在第一步中只是给这个二维数组的左下角元素赋了值,但是要输出山坡的形状,就要在每层元素前面输出不同的空格,来控制整体的输出形状。
示例代码如下:
private static void printTriangle(int num){ int[][] arr = new int[num][num]; /*给“山坡”的左右两边元素赋值*/ for(int i=0; i<num; i++) { arr[i][i] = 1; arr[i][0] = 1; } /*给“山坡”内部元素赋值,每个元素等于上层两个相邻元素之和*/ for(int i=2; i<num; i++) { for(int j=1; j<i; j++) { arr[i][j] = arr[i-1][j-1] + arr[i-1][j]; } } /*以山坡形状,输出所有元素*/ for(int i=0; i<10; i++) { for(int k=0; k<num-i; k++) { System.out.print(" "); } for(int j=0; j<=i; j++) { System.out.print(arr[i][j]+" "); } System.out.println(); } }
这道题考的内容也不多,即元素的比较和交换,示例代码如下:
/*arr:将要排序的数字放入数组中,isSscending:是否升序排列*/ private static void printThreeNum(int[] array,boolean isSscending){ for(int i=0;i<array.length-1;i++){ for(int j=0;j<array.length-1-i;j++){ /*升序*/ if(isSscending){ if(array[j]>array[j+1]){ int temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; } /*降序*/ }else{ if(array[j]<array[j+1]){ int temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; } } } } for(int i=0;i<array.length;i++){ System.out.print(array[i]+" "); } }
其实题目中的做法就是冒泡排序的优化方式,就是在一趟比较中同时找出两个最值,放到序列两端。就这个题而言,可以分为两步:找最大元素与最小元素的索引,然后再分别于数组首尾元素交换即可。示例代码如下:
private static void swapAndPrint(int[] arr){ int maxIndex=0; int minIndex=0; for(int i=0;i<arr.length;i++){ /*找到最小元素索引*/ if(arr[minIndex]>arr[i]){ minIndex=i; } /*找到最大元素索引*/ if(arr[maxIndex]<arr[i]){ maxIndex=i; } } int temp=0; /*最大元素与数组首元素交换*/ temp=arr[0]; arr[0]=arr[maxIndex]; arr[maxIndex]=temp; /*最小元素与数组尾元素交换*/ temp=arr[arr.length-1]; arr[arr.length-1]=arr[minIndex]; arr[minIndex]=temp; for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" "); }
要解决此题,需要创建一个大小为m的临时数组,用以临时存放元素,然后将m个元素之前的元素往后移,临时数组中存放的元素放在前m个位置。示例代码如下:
private static void move(int[] arr,int position){ if(position>=arr.length){ /*输入参数不合法*/ return; } /*将要移动的后m个元素存到临时数组中*/ int[] tempArr=new int[position]; for(int i=0;i<tempArr.length;i++){ tempArr[i]=arr[arr.length-position+i]; } /*将最后的m个元素之外的元素往后移*/ for(int i=0;i<arr.length-position;i++){ arr[i+position]=arr[i]; } /*将临时数组中的m个元素放回原数组的前m个位置*/ for(int i=0;i<tempArr.length;i++){ arr[i]=tempArr[i]; } for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" "); }
运行后却发现,输出结果不正确,在元素往后移的过程中,可能存在着重复赋值的过程。比如假设arr中有5个元素,要移动的元素个数为2,则存在如下错误:将arr[1]的值赋给arr[3],又赋给arr[5],造成了arr[3]和arr[5]位置上都是arr[3]的值,arr[5]值丢失。正确的做法是将该步骤的由前向后改成由后向前赋值即可。完整正确代码示例如下:
private static void move(int[] arr,int position){ if(position>=arr.length){ /*输入参数不合法*/ return; } /*将要移动的后m个元素存到临时数组中*/ int[] tempArr=new int[position]; for(int i=0;i<tempArr.length;i++){ tempArr[i]=arr[arr.length-position+i]; } /*将最后的m个元素之外的元素往后移*/ for(int i=arr.length-position-1;i>=0;i--){ arr[i+position]=arr[i]; } /*将临时数组中的m个元素放回原数组的前m个位置*/ for(int i=0;i<tempArr.length;i++){ arr[i]=tempArr[i]; } for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" "); }
该问题相对复杂,先不想具体的解题步骤,假设要解这道题,需要怎样的变量。首先需要一个数组或链表之类的数据结构,来存放n个数据。这n个数据要存什么呢?可以放一个boolean型或int型变量,用来标识是否已经退出。此外,还需要一个变量,来统计报到的数字(即1、2、3)。
万事俱备,现在要写东风(具体的步骤)了。首先要有一个最外层的循环,当还没淘汰的人数大于1时,就继续进行下去。然后判断当前报数人是否被淘汰,因为被淘汰的人是不继续报数的,然后判断是否报到了3,如果报到了3,将当前任淘汰,总数-1,报的数字从0开始。同时,要注意的事情是:当报数到最后一个人时,索引从0开始,即达到一个循环报数的效果。
示例代码如下:
private static int stay(int n){ boolean[] arr = new boolean[n]; for(int i=0; i<arr.length; i++) { arr[i] = true; } /*在统计范围内的总人数*/ int leftCount = n; /*当前报的数字*/ int countNum = 0; /*当前报数人的索引*/ int index = 0; /*当要统计的总人数>1时,继续游戏*/ while(leftCount > 1) { /*只统计未淘汰的人*/ if(arr[index] == true) { countNum++; if(countNum == 3) { /*当数到3时,从0开始,当前索引置为false,总人数-1*/ countNum =0; arr[index] = false; leftCount --; } } /*报数+1时,对应的人的索引也要+1*/ index ++; /*如果报数到了最后一个人时,循环计数*/ if(index == n) { index = 0; } } for(int i=0; i<n; i++) { if(arr[i] == true) { return i+1; } } return 0; }
这题目大概是要考对length这个词的使用,length有两个地方常常会用到,若不熟悉的话,可能会混淆:
1>在数组中,array.length是一个数组对象的属性。
2>在字符串中,string.length()是一个方法。
示例代码如下:
private static int length(String str){
return str.length();
}
这类题目在之前已经遇到过好几次了,这道题无非多了一个奇偶数的判断,剩下的就是每次求出一个符合一定规律的数,再求所有数的积或和。示例代码如下:
private static double sum(int n){
double sum=0.0;
if(n%2==0){
for(int i=2;i<=n;i=i+2){
double temp=(double)1/i;
sum=sum+temp;
}
}else{
for(int i=1;i<=n;i=i+2){
double temp=(double)1/i;
sum=sum+temp;
}
}
return sum;
}
该题目和比较一系列的数字实质上是一类问题,不过数字的比较换成了String的比较而已。进行String的比较时,可以将String拆分成char数组,对数组中的元素进行逐个比较。如果两个char数组在可以比较的范围(较小的数组长度)内均相同,那么就以较长的那个数组为较大的字符串。示例代码如下:
private static void stringSort(String[] strs){ for(int i=0;i<strs.length-1;i++){ for(int j=0;j<strs.length-1-i;j++){ /*比较规则:将string转换为char数组,然后再逐个比较char数组中的元素*/ if(compare(strs[i],strs[j])){ String temp=strs[j]; strs[j]=strs[j+1]; strs[j+1]=temp; } } } } private static boolean compare(String str1,String str2){ boolean flag=false; for(int i=0;i<str1.length()&&i<str2.length();i++){ if(str1.charAt(i)<str2.charAt(i)){ flag=true; return flag; } } if(str1.length()<str2.length()) flag=true; return flag; }
这种题目在之前的例子也出现了多次,就是一个不断重复某种操作,来求初始值或末尾值的过程,本题多的无非是未明确最后的值。本题末尾是求最小值,所以可假设最后剩余了一个桃子,来反推最初始的值,可以用递归的方式实现。示例代码如下:
private static int sum(int endNum){ int sum=0; int cnt=0; for(int i=endNum;i<10000;i++){ sum=i; cnt=0; for(int j=0;j<5;j++){ if(sum%5==1){ sum=sum-((sum/5)+1); cnt++; if(cnt==5){ return i; } }else{ break; } } } return 0; }
这个就是常见的一个在一定范围内求值的问题,搞懂题意,就好实现。本题的意思其实是:求一个两位数,这个两位数:乘以8小于100,乘以9大于等于100。示例代码如下:
private static int num(){
for(int i=10;i<13;i++){
if(8*i<100&&9*i>=100){
return i;
}
}
return 0;
}
该题目最简单的实现方法是暴力计算。实现代码如下:
private static int num(){
int count=0;
for(int i=1;i<76543210;i++) {
if(i%2!=0) {
count++;
}
}
return count;
}
该题可以转换为在2到制定的偶数之间求两个素数的过程,不过两个素数之和恰好等于该偶数。示例代码如下:
private static void printTwoPrime(int num){ if(num%2!=0){ System.out.println("不是偶数"); return; } int primeA=0; int primeB=0; for(int i=2;i<num;i++){ if(isPrime(i)){ primeA=i; } if(isPrime(num-i)){ primeB=num-i; System.out.println(num+"可以是素数"+primeA+"与"+primeB+"之和"); break; } } } private static boolean isPrime(int n){ for(int i=2;i<=(int)Math.sqrt(n);i++){ if(n==2) return true; else if(n%i==0) return false; } return true; }
该题考运算符和循环的使用,该题条件比较简单,用while循环就行。示例代码如下:
private static int count(int num){
int result=0;
while(num%9==0){
num=num/9;
result++;
}
return result;
}
关于字符串拼接的实及性能分析,有很多的内容需要了解,有机会的话在后续文章中进行简单介绍,在本题中,直接拼接两个字符串就行。示例代码如下:
private static String add(String str1,String str2){
return str1+str2;
}
该题主要考如何运用一个序列中的值,所以在这7个值的赋值上,此处做简化处理,直接赋值到一个数组中。示例代码如下:
private static void printStar(int[] arr){
for(int i=0;i<arr.length;i++){
for(int j=1;j<=arr[i];j++){
System.out.print("*");
}
System.out.println();
}
}
该提主要考的是如何计算出一个大数字不同位数上的数字,剩余的都是一些简单的计算。示例代码如下:
private static int encryption(int num){ int result=0; /*以下四个数字分别表示个十百千位*/ int part1=num%10; int part2=num%100/10; int part3=num/100%10; int part4=num/1000; /*接下来要对每个位数上的数字进行重复操作,所以在此处将各个数字存储到一个数组中,以便使用循环进行重复操作*/ int[] arr=new int[4]; arr[0]=part1; arr[1]=part2; arr[2]=part3; arr[3]=part4; for(int i=0;i<arr.length;i++){ arr[i]+=5; arr[i]=arr[i]%10; } swap(arr[0],arr[3]); swap(arr[1],arr[2]); result=arr[3]*1000+arr[2]*100+arr[1]*10+arr[0]; return result; } private static void swap(int a,int b){ int temp=a; a=b; b=temp; }
字符串匹配也是一类常见的题目,在本题中,可以先不考虑性能等因素,直接暴力匹配就行。在本题中,可以将两个字符串拆分成两个char数组,然后对子字符串转换成的char数组逐个比较,匹配成功,次数+1,直到总的字符串比较完成。示例代码如下:
private static int count(String str1,String str2){ int count=0; int tempCnt=0; for(int i=0;i<str1.length();i++){ for(int j=0;j<str2.length();j++){ if(str1.charAt(i)==str1.charAt(j)){ tempCnt++; if(tempCnt==str2.length()){ count++; tempCnt=0; break; } } } } return count; }
此题考的内容有点多,文件创建于读写此处省略,简单理解为求平均值。本题简化为创建一个二维数组,分别存不同学生的成绩,我们只要求学生成绩的平均值。示例代码如下:
private static double[] average(int[][] grades){
double[] result=new double[grades.length];
int sum=0;
for(int i=0;i<result.length;i++){
sum=0;
for(int j=0;j<grades[i].length;j++){
sum=sum+grades[i][j];
result[i]=(double)sum/3;
}
}
return result;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。