算法与编程

. 算法与编程

1、编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。

答:

                   packagecn.itcast;

 

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

 

public class MainClass{

         publicstatic void main(String[] args) throws Exception{

                   FileManagera = new FileManager("a.txt",new char[]{'\n'});

                   FileManagerb = new FileManager("b.txt",new char[]{'\n',' '});            

                   FileWriterc = new FileWriter("c.txt");

                   StringaWord = null;

                   StringbWord = null;

                   while((aWord= a.nextWord()) !=null ){

                            c.write(aWord+ "\n");

                            bWord= b.nextWord();

                            if(bWord!= null)

                                     c.write(bWord+ "\n");

                   }

                  

                   while((bWord= b.nextWord()) != null){

                            c.write(bWord+ "\n");

                   }      

                   c.close();

         }

        

}

 

 

class FileManager{

 

         String[]words = null;

         int pos =0;

         publicFileManager(String filename,char[] seperators) throws Exception{

                   Filef = new File(filename);

                   FileReaderreader = new FileReader(f);

                   char[]buf = new char[(int)f.length()];

                   intlen = reader.read(buf);

                   Stringresults = new String(buf,0,len);

                   Stringregex = null;

                   if(seperators.length>1 ){

                            regex= "" + seperators[0] + "|" + seperators[1];

                   }else{

                            regex= "" + seperators[0];

                   }

                   words= results.split(regex);

         }

        

         publicString nextWord(){

                   if(pos== words.length)

                            returnnull;

                   returnwords[pos++];

         }

 

}

 

2、编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad

(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)

答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FilenameFilter;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

 

public class Jad2Java {

 

         publicstatic void main(String[] args) throws Exception {

                   FilesrcDir = new File("java");

                   if(!(srcDir.exists()&& srcDir.isDirectory()))

                                     thrownew Exception("目录不存在");

                   File[]files = srcDir.listFiles(

                            newFilenameFilter(){

 

                                               publicboolean accept(File dir, String name) {

                                                        returnname.endsWith(".java");

                                               }

                                              

                                     }

                   );

                  

                   System.out.println(files.length);

                   FiledestDir = new File("jad");

                   if(!destDir.exists())destDir.mkdir();

                   for(Filef :files){

                            FileInputStream  fis = new FileInputStream(f);

                            StringdestFileName = f.getName().replaceAll("\\.java$", ".jad");

                            FileOutputStreamfos = new FileOutputStream(new File(destDir,destFileName));

                            copy(fis,fos);

                            fis.close();

                            fos.close();

                   }

         }

        

         private staticvoid copy(InputStream ips,OutputStream ops) throws Exception{

                   intlen = 0;

                   byte[]buf = new byte[1024];

                   while((len= ips.read(buf)) != -1){

                            ops.write(buf,0,len);

                   }

 

         }

}

 

由本题总结的思想及策略模式的解析:

1.

class jad2java{

         1. 得到某个目录下的所有的java文件集合

                   1.1得到目录 File srcDir = new File("d:\\java");

                   1.2得到目录下的所有java文件:File[]files = srcDir.listFiles(new MyFileFilter());

                   1.3只想得到.java的文件: class MyFileFilter implememytsFileFilter{

                            publicboolean accept(File pathname){

                                     returnpathname.getName().endsWith(".java")

                            }

                   }

                  

         2.将每个文件复制到另外一个目录,并改扩展名

                   2.1得到目标目录,如果目标目录不存在,则创建之

                   2.2根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。

                   2.3根据表示目录的File和目标文件名的字符串,得到表示目标文件的File

                            //要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。

                   2.4将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。

                            //方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。    

}

 

分析listFiles方法内部的策略模式实现原理

File[] listFiles(FileFilter filter){

         File[]files = listFiles();

         //ArraylistacceptedFilesList = new ArrayList();

         File[]acceptedFiles = new File[files.length];

         int pos =0;

         for(Filefile: files){

                   booleanaccepted = filter.accept(file);

                   if(accepted){

                            //acceptedFilesList.add(file);

                            acceptedFiles[pos++]= file;

                   }                

         }

        

         Arrays.copyOf(acceptedFiles,pos);

         //return(File[])accpetedFilesList.toArray();

        

}

3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,

public static booleanisLetter(char c){
  

 int k=0X80;
   

returnc/k==0?true:false;  
   
   

}
   
   

public static intlengths(String strSrc){
   

if (strSrc==null){
      

return 0;
   

}
   

int len=0;
   

char[] strChar=strSrc.toCharArray();
   

for (inti=0;i<strChar.length;i++){
      

len++;
      

if (!isLetter(strChar[i]))len++;     
   

}
   

return len;   
   

}
   
   

public static StringsubString(String origin,int len){
   

if (origin==null || origin.equals("")||len<1){
      

return"";
   

}
   

if(len>lengths(origin)){
      

return origin;     
   

}
   

byte[] strByte=newbyte[len];
   

System.arraycopy(origin.getBytes(),0,strByte,0,len);
   

int count=0;
   

for (int i=0;i<len;i++){
      

intvalue=(int)strByte[i];
      

if (value<0) count++;  
   

}
   

if (count % 2!=0){
     

 len=(len==1)?++len:--len;
   

}
   

return newString(strByte,0,len);
   
   

}  

public static voidmain(String[] args) {
           

System.out.println(""+subString("我ABC汉DEF",6));
  
}

4,应该截取“我AB”,输入“我ABCDEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。

答:

         首先要了解中文字符有多种编码及各种编码的特征。

    假设n为要截取的字节数。

         publicstatic void main(String[] args) throws Exception{

                   Stringstr = "a爱中华abc我爱传智def';

                   Stringstr = "ABC";

                   intnum = trimGBK(str.getBytes("GBK"),5);

                   System.out.println(str.substring(0,num));

         }

        

         publicstatic int  trimGBK(byte[] buf,int n){

                   intnum = 0;

                   booleanbChineseFirstHalf = false;

                   for(inti=0;i<n;i++)

                   {

                            if(buf[i]<0&& !bChineseFirstHalf){

                                     bChineseFirstHalf= true;

                            }else{

                                     num++;

                                     bChineseFirstHalf= false;                                

                            }

                   }

                   returnnum;

         }

4、有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数。

答:哈哈,其实包含中文字符、英文字符、数字字符原来是出题者放的烟雾弹。

String content = “中国aadf111bbb菲的zz萨菲”;

HashMap map = new HashMap();

for(int i=0;i<content.length;i++)

{

         charc = content.charAt(i);

         Integernum = map.get(c);

         if(num== null)

                   num= 1;

         else

                   num= num + 1;

         map.put(c,num);

}

for(Map.EntrySet entry : map)

{

         system.out.println(entry.getkey()+ “:” + entry.getValue());

}

估计是当初面试的那个学员表述不清楚,问题很可能是:

如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。

int engishCount;

int chineseCount;

int digitCount;

for(int i=0;i<str.length;i++)

{

     char ch = str.charAt(i);

     if(ch>=0 && ch<=9)

     {

         digitCount++

     }

     elseif((ch>=a && ch<=z) || (ch>=A && ch<=Z))

     {

         engishCount++;

     }

     else

     {

         chineseCount++;

     }

}

System.out.println(……………);

 

5、说明生活中遇到的二叉树,用java实现二叉树

这是组合设计模式。

我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:

代码如下:

packagecom.huawei.interview;

 

public classNode {

    public int value;

    public Node left;

    public Node right;

   

    public void store(intvalue)

    {

        if(value<this.value)

        {

            if(left == null)

            {

                left = new Node();

                left.value=value;

            }

            else

            {

                left.store(value);

            }

        }

        else if(value>this.value)

        {

            if(right == null)

            {

                right = new Node();

                right.value=value;

            }

            else

            {

                right.store(value);

            }          

        }

    }

   

    public boolean find(intvalue)

    {  

        System.out.println("happen" + this.value);

        if(value == this.value)

        {

            return true;

        }

        else if(value>this.value)

        {

            if(right == null) returnfalse;

            return right.find(value);

        }else

        {

            if(left == null) returnfalse;

            return left.find(value);

        }

 

    }

   

    public  void preList()

    {

        System.out.print(this.value+ ",");

        if(left!=null)left.preList();

        if(right!=null)right.preList();

    }

   

    public void middleList()

    {

        if(left!=null)left.preList();

        System.out.print(this.value+ ",");

        if(right!=null)right.preList();       

    }

    public void afterList()

    {

        if(left!=null)left.preList();

        if(right!=null) right.preList();

        System.out.print(this.value+ ",");    

    }  

    public static voidmain(String [] args)

    {

        int [] data = new int[20];

        for(inti=0;i<data.length;i++)

        {

            data[i] = (int)(Math.random()*100)+ 1;

            System.out.print(data[i] +",");

        }

        System.out.println();

       

        Node root = new Node();

        root.value = data[0];

        for(inti=1;i<data.length;i++)

        {

            root.store(data[i]);

        }

       

        root.find(data[19]);

       

        root.preList();

        System.out.println();

        root.middleList();

        System.out.println();      

        root.afterList();

    }

}

6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:

1,张三,28

2,李四,35

3,张三,28

4,王五,35

5,张三,28

6,李四,35

7,赵六,28

8,田七,35

 

程序代码如下(答题要博得用人单位的喜欢,包名用该公司,面试前就提前查好该公司的网址,如果查不到,现场问也是可以的。还要加上实现思路的注释):

packagecom.huawei.interview;

 

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.io.InputStream;

importjava.io.InputStreamReader;

importjava.util.Comparator;

importjava.util.HashMap;

importjava.util.Iterator;

importjava.util.Map;

importjava.util.TreeSet;

 

 

public classGetNameTest {

 

    /**

     * @paramargs

     */

    public static voidmain(String[] args) {

        // TODO Auto-generated methodstub

        //InputStream ips =GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");

        //用上一行注释的代码和下一行的代码都可以,因为info.txtGetNameTest类在同一包下面,所以,可以用下面的相对路径形式

       

        Map results = new HashMap();

        InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");

        BufferedReader in = newBufferedReader(new InputStreamReader(ips));

        String line = null;

        try {

            while((line=in.readLine())!=null)

            {

                dealLine(line,results);

            }

            sortResults(results);

        } catch (IOException e) {

            // TODO Auto-generated catchblock

            e.printStackTrace();

        }

    }

   

    static class User

    {

        public  String name;

        public Integer value;

        public User(String name,Integervalue)

        {

            this.name = name;

            this.value = value;

        }

 

        @Override

        public booleanequals(Object obj) {

            // TODO Auto-generated methodstub

               

            //下面的代码没有执行,说明往treeset中增加数据时,不会使用到equals方法。

            boolean result = super.equals(obj);

            System.out.println(result);

            return result;

        }

    }

   

    private static voidsortResults(Map results) {

        // TODO Auto-generated methodstub

        TreeSet sortedResults = new TreeSet(

                new Comparator(){

                    public intcompare(Object o1, Object o2) {

                        // TODOAuto-generated method stub

                        User user1 = (User)o1;

                        User user2 = (User)o2;

                        /*如果compareTo返回结果0,则认为两个对象相等,新的对象不会增加到集合中去

                         * 所以,不能直接用下面的代码,否则,那些个数相同的其他姓名就打印不出来。

                         * */

                       

                        //returnuser1.value-user2.value;

                        //returnuser1.value<user2.value?-1:user1.value==user2.value?0:1;

                        if(user1.value<user2.value)

                        {

                            return -1;

                        }else if(user1.value>user2.value)

                        {

                            return1;

                        }else

                        {

                            returnuser1.name.compareTo(user2.name);

                        }

                    }

                   

                }

        );

        Iterator iterator =results.keySet().iterator();

        while(iterator.hasNext())

        {

            String name =(String)iterator.next();

            Integer value =(Integer)results.get(name);

            if(value > 1)

            {              

                sortedResults.add(newUser(name,value));               

            }

        }

       

        printResults(sortedResults);

    }

    private static voidprintResults(TreeSet sortedResults)

    {

        Iterator iterator  = sortedResults.iterator();

        while(iterator.hasNext())

        {

            User user = (User)iterator.next();

            System.out.println(user.name+ ":" + user.value);

        }  

    }

    public static voiddealLine(String line,Map map)

    {

        if(!"".equals(line.trim()))

        {

            String [] results = line.split(",");

            if(results.length == 3)

            {

                String name = results[1];

                Integer value =(Integer)map.get(name);

                if(value == null)value = 0;

                map.put(name,value + 1);

            }

        }

    }

 

}

7、写一个Singleton出来。

第一种:饱汉模式

publicclass SingleTon {

    private SingleTon(){

        }

 

    //实例化放在静态代码块里可提高程序的执行效率但也可能更占用空间

    private final static SingleTon instance =new SingleTon();

    public static SingleTon getInstance(){

        return instance;

    }

}

 

第二种:饥汉模式

public classSingleTon {

    private SingleTon(){}

   

    private static instance = null;//newSingleTon();

   

    public static synchronized SingleTongetInstance(){

        if(instance == null)

            instance = new SingleTon();

        return instance;

    }

}

 

第三种:用枚举

    public enum SingleTon{

        ONE;

   

    }

 

第三:更实际的应用(在什么情况用单例)

publicclass SequenceGenerator{

    //下面是该类自身的业务功能代码

    private int count = 0;

 

    public synchronized int getSequence(){

        ++count;

    }

   

    //下面是把该类变成单例的代码

    private SequenceGenerator(){}

    private final static instance = new SequenceGenerator();

    public static SingleTon getInstance(){

        return instance;

    }  

   

}

 

第四:

    public class MemoryDao

    {

    private HashMap map = new HashMap();

   

   publicvoid add(Student stu1){

        map.put(SequenceGenerator.getInstance().getSequence(),stu1);

    }

  

   //MemoryDao变成单例

  }

 

 

 

 

 

 

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

一般Singleton模式通常有几种种形式:

第一种形式: 定义一个类,它的构造函数为private的,它有一个staticprivate的该类变量,在类初始化时实例话,通过一个publicgetInstance方法获取对它的引用,继而调用其中的方法。

public class Singleton {

private Singleton(){}

    //在自己内部定义自己一个实例,是不是很奇怪?

    //注意这是private只供内部调用

    private static Singleton instance = newSingleton();

    //这里提供了一个供外部访问本class的静态方法,可以直接访问  

    public static Singleton getInstance() {

    return instance;

    }

   }

   第二种形式:

public class Singleton {

private static Singletoninstance = null;

public static synchronizedSingleton getInstance() {

//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次   

//使用时生成实例,提高了效率!

if (instance==null)

instancenewSingleton();

                    returninstance;

    }

}

其他形式:

定义一个类,它的构造函数为private的,所有方法为static的。

一般认为第一种形式要更加安全些

8、递归算法题1

一个整数,大于0,不用循环和本地变量,按照n,2n,4n,8n的顺序递增,当值大于5000时,把值按照指定顺序输出来。
例:n=1237
则输出为:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,

提示:写程序时,先致谢按递增方式的代码,写好递增的以后,再增加考虑递减部分。

    public static void doubleNum(int n)

    {

        System.out.println(n);

        if(n<=5000)

            doubleNum(n*2);

        System.out.println(n);     

    }

 


9、递归算法题2

第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?

packagecn.itcast;

 

importjava.util.Date;

 

public classA1 {

 

    public static voidmain(String [] args)

    {

        System.out.println(computeAge(8));

    }

   

    public static int computeAge(intn)

    {

        if(n==1) return 10;

        return computeAge(n-1) + 2;

    }

}

 

    public static voidtoBinary(int n,StringBuffer result)

    {

 

        if(n/2 != 0)

            toBinary(n/2,result);

        result.append(n%2);    

    }

10、排序都有哪几种方法?请列举。用JAVA实现一个快速排序。

 本人只研究过冒泡排序、选择排序和快速排序,下面是快速排序的代码:

public class QuickSort {
/**
*
快速排序
* @param strDate
* @param left
* @param right
*/
public void quickSort(String[] strDate,int left,int right){
String middle,tempDate;
int i,j;
i=left;
j=right;
middle=strDate[(i+j)/2];
do{
while(strDate[i].compareTo(middle)<0&& i<right)
i++; //
找出左边比中间值大的数
while(strDate[j].compareTo(middle)>0&& j>left)
j--; //
找出右边比中间值小的数
if(i<=j){ //
将左边大的数和右边小的数进行替换
tempDate=strDate[i];
strDate[i]=strDate[j];
strDate[j]=tempDate;
i++;
j--;
}
}while(i<=j); //
当两者交错时停止

if(i<right){
quickSort(strDate,i,right);//

}
if(j>left){
quickSort(strDate,left,j);
}
}
/**
  * @param args
  */
public static void main(String[] args){
String[] strVoid=newString[]{"11","66","22","0","55","22","0","32"};
QuickSort sort=new QuickSort();
sort.quickSort(strVoid,0,strVoid.length-1);
for(int i=0;i<strVoid.length;i++){
System.out.println(strVoid[i]+" ");
}
}


}

11、有数组a[n],用java代码将数组元素顺序颠倒

//用下面的也可以

//for(int i=0,int j=a.length-1;i<j;i++,j--) 是否等效于 for(inti=0;i<a.length/2;i++)

 

importjava.util.Arrays;

 

publicclass SwapDemo{

 

    public static void main(String[] args){

        int [] a = new int[]{

                        (int)(Math.random() *1000),

                        (int)(Math.random() *1000),

                        (int)(Math.random()* 1000),

                        (int)(Math.random() * 1000),                       

                        (int)(Math.random()* 1000)                                                                    

        }; 

       

        System.out.println(a);

        System.out.println(Arrays.toString(a));

        swap(a);

        System.out.println(Arrays.toString(a));    

    }

   

    public static void swap(int a[]){

        int len = a.length;

        for(int i=0;i<len/2;i++){

            int tmp = a[i];

            a[i] = a[len-1-i];

            a[len-1-i] = tmp;

        }

    }

}

12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。

去零的代码:

     returnsb.reverse().toString().replaceAll("[拾佰仟]","").replaceAll("+","").replaceAll("+","").replaceAll("+","");

 

public class RenMingBi {

 

         /**

          * @param args add by zxx ,Nov 29, 2008

          */

         privatestatic final char[] data = new char[]{

                            '','','','','','','','','',''

                   };

         privatestatic final char[] units = new char[]{

                   '','','','','','','','','亿'

         };

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   System.out.println(

                                     convert(135689123));

         }

 

         publicstatic String convert(int money)

         {

                   StringBuffersbf = new StringBuffer();

                   intunit = 0;

                   while(money!=0)

                   {

                            sbf.insert(0,units[unit++]);

                            intnumber = money%10;

                            sbf.insert(0,data[number]);

                            money/= 10;

                   }

 

                   returnsbf.toString();

         }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值