文章目录
- 1.大小写转换
- 2.斐波那契数列
- 2.1递归解决(不推荐)
- 2.2递推公式(非递归)
- 3.删除公共字符
- 3.1题目说明
- 3.2第一种方法
- 3.3第二种方法
- 4.字符串的加法
- 4.1题目说明
- 4.2题目核心方法
- 4.3题目代码解析
Java初阶测试编程题目分析与总结:
1.大小写转换
- 我们这个转换就是每一行会把这个大写的转换为小写的,这个大小写之间的这个编码值相差的是32;
- in.next()对于这个大写字符内容进行读取操作;
- str.charAt(0)就是把这个读取的大写字符+32转换为小写的,因为这个一行就只有一个大写的字符,因此这个时候我们直接传递0下标就可以了;
- str.charAt(0)返回的是一个char类型的值,但是这个值是字符的unicode编码值,加上32之后依然是一个整数,这个时候我们需要进行强制类型转换为char类型的数据,这样才可以得到小写的字母;
2.斐波那契数列
2.1递归解决(不推荐)
这个关于斐波那契数列的问题,其实已经屡见不鲜了,但是这个题目确实值得我们反复琢磨
递归的写法就是前面的连个返回1,后面的从第三个开始就不断的进行递归计算,这个思路很简答,但是效率不行,不建议写这个;
2.2递推公式(非递归)
递推公式这个和递归相比,其实无论是时间和空间上面都是有提升的,因此这个才是我们推荐的写法;
这个是我在牛客上面看到的一个解法,确实很清晰,我们都知道这个递推公式需要不断的进行更新,但是这个实现的时候其实没有上面的递归那么无脑,因为这个中间的过程需要我们自己写出来,但是递归就是直接return前面的两项进行相加,这个其实很复杂,但是我们不需要自己实现;
这个就是ret1=1,ret2=1,如果是后面的这个,我们就进行这个ret1,ret2的更新:
1 1 2 3 5;
例如我们的这个过程,其实就是ret1指向第一个1,ret2指向第二个1,然后我们把这个ret1给了ret2,把这个第三个数据result给了这个ret1,依次进行下去,这个过程其实和我们的高中时期学习的数列很相似,不断地利用递推公式求解下一项;
3.删除公共字符
3.1题目说明
这个题目是一个公司的笔试题目,是让我们从两个单词里面进行比较,看看第一个单词去掉第二个单词里面的字符之后还剩下什么;
3.2第一种方法
- 首先我们使用这个nextLine读取两个单词,分别存储到这个str1,str2里面去,因为这个nextLine不是读取这一行的内容,因此会分别读取到两个单词;
- func里面先是创建一个对象,取出来这个str1里面的每一个字符,如果这个str2里面没有,我们就是用这个append方法把这个字符添加到我们的这个创建的对象里面去;
- contains这个方法就是进行查看我们的str1里面的字符是不是在这个str2里面,这个方法的参数是string类型的,但是我们的这个ret是字符类型的,我们在这个后面加上“”之后就可以把这个字符串转换为string类型的;
- 因为我们最后打印输出的还是一个单词,因此我们要使用这个toString的方法,把这个对象转换为String字符串类型数据,作为返回值;
- 我们在这个过程中使用的是对象,因为这个对象可以使用append对于这个对象的内容进行修改,但是我们最后还是要转换回去,达到了曲线救国的目的;
3.3第二种方法
- 我们核心思路就是判断这个第一个字符串里面的字符是不是第二个字符串里面出现了,因此,除了上面的这个contains方法,我们其实还是可以使用这个indexOf方法的;
- str2.indexOf(ch)就是返回这个ch(str1里面的字符),在str2里面的下标,如果存在就是返回下标,不存在返回-1,因此如果这个循环判断的过程中。如果这个indexof的返回值是-1,就说明我们的这个str1里面的这个元素没有在str2里面,这个时候我们还是使用append方法进行添加到对象里面去;
- 通过这个题目,我们可以发现其实这个全部一样,就是判断的方法使用的是不同的方式罢了,我在学习这个string的时候,总觉得老师讲了很多的方法,不知道孰轻孰重,相信很多的初学者都有这个体会,但是在这个刷题的过程中,我认为这个出现的方法例如这个contains,indexof这些就是值得我们归纳和总结的;
4.字符串的加法
4.1题目说明
这个题目也是相当有难度的,当然这个是对于初学者而言的,反正我自己是对于这个问题没有任何思路,之前也写过类似的这个大数乘法之类的这样的题目,但是使用觉得很困难,这个题目和之前也是很相似的;
4.2题目核心方法
对于两个二进制的字符串进行相加,我们的情况有以下的几种:
上面的是情况分类,我们的设计程序还是基于这个数位不相同的情况进行设计:
首先对于二进制字符串,我们首先需要进行数位对齐相加,然后是reverse操作,因为我们加的时候是从低到高的,但是我们为了我们的下标更好控制,进行逆置,这样的话,我们的加法就是从第一个开始加(实际上是最高位),然后是进行逆置回去即可;
下面的这个就是大致一个思路过程:
4.3题目代码解析
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String a = in.next();
String b = in.next();
String ret = add(a,b);
System.out.println(ret);
}
}
private static String add(String a,String b){
StringBuilder stringBuilder = new StringBuilder();
int len1 = a.length();
int len2 = b.length();
int maxLen = Math.max(len1,len2);
StringBuilder stringBuilderA = new StringBuilder(a).reverse();
StringBuilder stringBuilderB = new StringBuilder(b).reverse();
boolean isForward = false;//这个就是说:默认没有进位
for(int i=0;i<maxLen;i++){
char cha = i>=len1 ? '0':stringBuilderA.charAt(i);//这个是使用的三目进行判断是否需要添加0,因为这个添加0的操作只有两个数据的位数不一样的时候才会用到;
//i>=len1的时候说明这两个的数位不一样,因此我们需要补上0;
//例如1010
// 10001 这个当i走到第四个的时候,因为有一个数据的第五位上面有数,因此我们两个都需要向后走,这个时候的i>=len1就起作用了,这个时候我们就需要补上0,因为这个要和10001进行add吗,否则无法进行下面的分支判断
char chb = i>=len2 ? '0':stringBuilderB.charAt(i);//和上面类似
if(cha == '1' && chb == '1'){
stringBuilder.append(isForward ? '1':'0');
isForward = true;//表示当前开始进位
}else if(cha=='0' && chb == '0'){
stringBuilder.append(isForward ? '1':'0');
isForward = false;
}else{
stringBuilder.append(isForward ? '0':'1');
}
}
if(isForward){
stringBuilder.append('1');
}
return stringBuilder.reverse().toString();
}
}
这个程序里面概括了所有情况:
- 首先分别求得nextLine得到的字符串的长度,求得最大值,这个最大值我们后面会用到的,然后这个三目的那个就是进行判断:是不是需要补上0,0补在什么位置上面;
- 三层if的分支是列举所有情况:1+1有进位就是1,1+1没有进位就是0,这个使用的是三目进行控制的,这个isForward就是判断这个时候是不是有进位,默认的这个false是没有进位的,1+1的话肯定有进位,这个时候我们就把这个改为true进行标记,如果是0+0这个时候肯定没有进位,这个时候再赶回去
- 也就是说这个过程里面的isForward是一直在更新的,因为这个和我们的实际的情况有关;
- 1+0或者0+1就是在这个else里面,这个里面没有对于这个isForward进行判断,主要就是因为这个没有必要,下面我来详细的说明一下这个位置为什么不进行判断:
- 如果原来是1+1总金额个时候经过判断,isforward就是true,这个时候是进位的买这个时候如果下一个是0+1/1+0的时候,我们的这个位置打印的就是0,这个时候进一位,还是true,和原来一样;
- 如果原来是0+0,isforward就是false,这个时候我们1+0还是0+1都是不需要进位的,还是false,这个也是不变的;
- 如果原来还是这个0+1或者1+0,这个时候原来的情况无非就是true或者false,我们上面已经分析了,无论是true还是false,我们的这个else里面执行之后都是不变的,因此,我们不用进行判断,否则,我们还要分情况进行判断,这个如果分析到了上面的4,5,6点,其实会发现我们完全没有必要进行判断,因为经过这个else,这个idforward是保持原样的;
- 在这个while循环之外的这个判断主要就是我们的这个111+101这样的情况,相加之后变成了四位数,这个时候我们进行额外的判断即可;
则,我们还要分情况进行判断,这个如果分析到了上面的4,5,6点,其实会发现我们完全没有必要进行判断,因为经过这个else,这个idforward是保持原样的; - 在这个while循环之外的这个判断主要就是我们的这个111+101这样的情况,相加之后变成了四位数,这个时候我们进行额外的判断即可;
- 经历上面的所有操作,最后还是需要把这个对象进行toString操作,并且进行逆置的,这样得到的就是我们的结果;