黑马程序员-重要代码记录
(原打算一个帖子收集,发现多了就不方便回顾,特另开)
1.关于猫狗鱼问题的思路
我的代码:
import java.util.ArrayList;
import java.util.Random;
public class Cross_new {
public static void main(String[] args) {
//开始过河.
doTransport();
}
public static void doTransport() {
// 抽象出猫,鱼,狗和两岸.
ArrayList<String> arr1 = new ArrayList<String>();
ArrayList<String> arr2 = new ArrayList<String>();
arr1.add("鱼");
arr1.add("猫");
arr1.add("狗");
// 农夫将要携带到船上动物.(前一字符表示农夫当前携带动物,后一字符表示上次农夫携带的动物,为了让农夫不出现重复拿同一个动物的情况)
System.out.println("农夫,猫,鱼,狗都在此岸,开始过河.\n");
String boat = new String("--");
while (arr1.size() > 0) {
move(arr1, arr2, boat);
}
System.out.println("\n农夫,猫,鱼,狗都到达彼岸.");
}
public static void move(ArrayList<String> arr1, ArrayList<String> arr2,String boat) {
//农夫船上是否有动物,有则不需随机选择携带.
if (boat.startsWith("-")) {
int one=0;
do{
// 农夫从此岸随机带上一个动物.
one = new Random().nextInt(arr1.size());
}while(arr1.get(one)==boat.substring(1, 2));
boat = arr1.get(one)+boat.substring(1,2);
arr1.remove(one);
}
// 判断此岸是否和谐
if (ifNice(arr1)) {
// 此岸和谐,农夫则将动物送去彼岸.
arr2.add(boat.substring(0, 1));
System.out.println("--->农夫带" + boat.substring(0, 1) + "去彼岸 ");
//首先判断是否将三个动物都放彼岸,是则无需判断是否和谐.
if(arr2.size()==3){
return;
}
// 判断彼岸是否和谐.
if (ifNice(arr2)) {
// 彼岸和谐,农夫则完成此次运送.
boat="-"+boat.substring(0, 1);
System.out.println(" 农夫单独回此岸<---");
} else {
// 彼岸不和谐,农夫则将岸上动物与携带动物交换.送回此岸.
boat=arr2.get(0)+boat.substring(0, 1);
System.out.println(" 农夫带" +boat.substring(0, 1)+ "回此岸<---");
arr2.remove(0);
arr1.add(boat.substring(0, 1));
boat="-"+boat.substring(0, 1);
}
} else {
// 如果此岸不和谐则放回此岸.
arr1.add(boat.substring(0, 1));
boat="-"+boat.substring(0,1);
}
}
public static boolean ifNice(ArrayList<String> arr) {// 判断是能否共存.
if ((arr.contains("猫") && arr.contains("狗"))
|| (arr.contains("鱼") && arr.contains("猫"))) {
return false;
} else {
return true;
}
}
}
朋友的代码:
public class Test10_1 {
public static void main(String[] args) {
// 首先创建三个对象
Animal cat = new Cat("cat");
Animal dog = new Dog("dog");
Animal fish = new Fish("fish");
// 定义两个链表存放对象
LinkedList<Animal> beforeCrossing = new LinkedList<Animal>();
LinkedList<Animal> afterCrossing = new LinkedList<Animal>();
beforeCrossing.add(cat);
beforeCrossing.add(dog);
beforeCrossing.add(fish);
while (beforeCrossing.size() != 0) {
// 从beforeCrossing取出一个Animal
Animal ani = beforeCrossing.removeFirst();
// 如果剩下两个Animal,看看剩下的Animal能否和平共处
if (beforeCrossing.size() == 2) {
if (beforeCrossing.getFirst().friendlyWith(beforeCrossing.getLast())) {
// 如果能合同共处,把取出的动物送到afterCrossing
afterCrossing.addLast(ani);
System.out.println(ani.getName() + "被送到对岸");
} else {
// 如果剩下的动物不能和平共处,则把取出的Animal再次插入beforeCrossing
beforeCrossing.addLast(ani);
}
} else {
// 否则先把动物送到对岸
afterCrossing.addLast(ani);
System.out.println(ani.getName() + "被送到对岸");
// 再判断对岸的Animal能否和平共处
if (afterCrossing.size() == 2) {
// 如果不能和平共处,则把对岸的原先的动物给送回来
if (!afterCrossing.getFirst().friendlyWith(afterCrossing.getLast())) {
ani = afterCrossing.removeFirst();
beforeCrossing.addLast(ani);
System.out.println(ani.getName() + "被送了回来");
}
}
}
}
}
}
abstract class Animal {
private String name;
public Animal() {
super();
}
public Animal(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract boolean friendlyWith(Animal ani);
}
class Cat extends Animal {
public Cat() {
super();
// TODO Auto-generated constructor stub
}
public Cat(String string) {
super(string);
}
@Override
public boolean friendlyWith(Animal ani) {
if (ani.getClass().getSimpleName().equals("Dog")
|| ani.getClass().getSimpleName().equals("Fish"))
return false;
else
return true;
}
}
class Dog extends Animal {
public Dog() {
super();
// TODO Auto-generated constructor stub
}
public Dog(String string) {
super(string);
}
@Override
public boolean friendlyWith(Animal ani) {
if (ani.getClass().getSimpleName().equals("Cat"))
return false;
else
return true;
}
}
class Fish extends Animal {
public Fish() {
super();
// TODO Auto-generated constructor stub
}
public Fish(String string) {
super(string);
}
@Override
public boolean friendlyWith(Animal ani) {
if (ani.getClass().getSimpleName().equals("Cat"))
return false;
else
return true;
}
}
总结:
这道题是从黑马基础题上看到的,刚开始以为没什么知识点,纯if判断就ok.后来才发现,可以很有知识点,
1.我再上面放出的第一个代码是我的思路.第二个是以朋友的思路.
我的代码在一开始,就没有我朋友的那种相当浓烈的面向对象思想.他将猫狗鱼都封装成了类,继承动物类,有方法Friendly.对于Java的面向对象思想来说,貌似很切合.
我的代码思路就是抽象了两岸,小船,用集合和String[]抽象了他们,并将动物抽象为了字符数组中的字符.虽然,我自认为自己的方法看起来更简单,但是不得不承认,思想上,败给了朋友的代码.
所以,我觉得Java前期的学习,必须注重思维的培养,培养面向对象的思想,深化封装,继承,多态的思维模式.
有了思想,语言基础都是可以用时间补上的....
----------------------------------------------------------
2.按字节为截取字符代码引发的思考
我的代码:
/*
* 需求:
* 编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
* 例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文.
*
* 思路:
* 字符串的字节文件表示中,英文字母为一个byte型数据表示,而汉子为两个byte数据表示.
* 对给定的一个字符串,用toCharArray()和getByte()方法分别转换为字符,字节数组.
* 如果是字母,则对应数组中元素的数值应该是相等的,否则不等,且为字节数组中两个元素对应字符数组中一个元素.
*
* 步骤:
* 1.键盘录入一个字符串对象.
* 2.转换并接受用String类中方法得到的字符数组与字节数组.
* 3.键盘接收需要截取字符串的字节数.
* 4.以字节数组元素来判定截取字节数,以与字符串数组元素的对比判断是否该将对应字符截取.
* 5.打印出截取后字符串.
* */
public class Test10 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入需要截取的字符串:");
String str = in.nextLine();
subPartOfString(str);
}
//定义方法,按需求截取字符串中对应字节字符串.
public static void subPartOfString(String str) {
Scanner in = new Scanner(System.in);
char[] charArr = str.toCharArray();
byte[] byteArr = str.getBytes();
int n = 0;
while (true) {
System.out.println("请输入需要截取字节数:(数字)");
n = in.nextInt();
if (n > byteArr.length || n <= 0) {
System.out.println("输入的截取字节数有误,请重新输入.");
continue;
} else {
break;
}
}
int j = 0, i = 0, count = 1;//i用于控制截取字节数,即循环增量;j为截取后字符数.
while (i < n) {
if (charArr[j] - byteArr[i] == 0) {//如果当前字节位为字母,则加入截取后字符串.
i++;
j++;
} else {//如果当前字节为汉子,则占两个字节,当且仅当截取了两个字节才将该字符加入截取后字符串.
count++;
i++;
j += count % 2;
}
}
System.out.println("截取后新字符串为:\n"+new String(charArr, 0, j));
}
}
张孝祥老师的方法代码:
public static void main(String[] args) throws Exception{
String str = "我a爱中华abc我爱传智def';
String str = "我ABC汉";
int num = trimGBK(str.getBytes("GBK"),5);
System.out.println(str.substring(0,num) );
}
public static int trimGBK(byte[] buf,int n){
int num = 0;
boolean bChineseFirstHalf = false;
for(int i=0;i<n;i++)
{
if(buf[i]<0 && !bChineseFirstHalf){
bChineseFirstHalf = true;
}else{
num++;
bChineseFirstHalf = false;
}
}
return num;
}
总结:
在这里,先对已逝的张孝祥老师报以有种的感谢...您一路走好.
这道题,也是从黑马入学基础题目中侬到的题目.在自己解决的时候,对如何判断是否截取这个占用了两个字节的一个汉子字符相当繁琐,多定义了两个集合,多用了几个循环增量.在看张孝祥老师的就业面试宝典时,突然发现,这道题老师的代码,很好.
我是这么顺着老师的代码走的思路:
1.方法定义中的参数列表为:一个由目标字符串转换成的字节数组,截取的字节数.
2.方法中,在循环截取的代码外,定义了截取长度的初始值0
,一个判断是否为中文字符的布尔变量.for循环的判断中,用字节数据是否为负数
(汉子由两个负的字节数据组成)和是否截取过1个字符的前一个字节.
3.
在循环体结束(两处,if和else)中分别对该辅助判断的布尔变量进行新的赋值
.
4.返回该结果.
事实上,我自己的代码中思路何老师差不多,但是没能思路明了的用一个布尔型变量来接收.实际上就是封装了我代码中的循环增量判断和赋值.其实想想也是,当循环增量是以模2为判断辅助条件,用false,或true,完全可以既简便由明了的替代这个循环增量.
总之,学习老师等高手的思想,思路,路还很长...
----------------------------------------------------------------------
详情请查看:http://edu.csdn.net/