黑马程序员技术交流社区

标题: 代码分享与探讨,基础测试的一个简单题目,有无更简单方法 [打印本页]

作者: 烟海    时间: 2014-9-2 00:31
标题: 代码分享与探讨,基础测试的一个简单题目,有无更简单方法
本帖最后由 烟海 于 2014-9-2 00:32 编辑

需求:
从键盘接受一个数字,打印该数字表示的时间,最大单位到天,例如:
键盘输入6,打印6秒;
键盘输入60,打印1分;
键盘输入66,打印1分6秒;
键盘输入666,打印11分6秒;
键盘输入3601,打印1小时1秒


需求很简单,代码实现的话,其实也没太复杂,不过思路分析,以及思考的过程,还是有些麻烦的,
分享一个自己写的,认为可能最简洁的代码了,贴出来探讨下,看看有无更简洁的方法。这里考虑到了999天的情况,更多的就没考虑了。
  1. import java.util.*;
  2. public class Test3 {
  3.         public static void main(String[] args) {
  4.                 int time = new Scanner(System.in).nextInt();
  5.                 printTime(time);
  6.         }
  7.         public static void printTime(int time){
  8.                 String[] str = {"时","分","秒"};
  9.                 for (int j = 0 ,i = 3600; time>0; i/=60,j++) {
  10.                         if(time>=86400){
  11.                                 System.out.print(time/86400+"天");
  12.                                 time = time%24;
  13.                         }
  14.                         if(time>=i){
  15.                                 if(time==0){}
  16.                                 else{
  17.                                         System.out.print(time/i+str[j]);
  18.                                 }
  19.                                 time = time%i;
  20.                         }
  21.                 }
  22.         }
  23. }
复制代码







作者: fantacyleo    时间: 2014-9-2 02:42
思路差不多就是这样了,跟把一个整数转为中文表示(如1002转为一千零二)是类似的,我是想不出再改进的办法了,时间复杂度是log(N)也很不错了
作者: 烟海    时间: 2014-9-2 11:45
fantacyleo 发表于 2014-9-2 02:42
思路差不多就是这样了,跟把一个整数转为中文表示(如1002转为一千零二)是类似的,我是想不出再改进的办法 ...

那个整数转出中文显示。。。比这个还复杂挺多。。。
那一题,困扰了我将近2天的时间。。最后才用最笨的方法解决了。。。

然后最后完全解决之后,才想起来有稍微简单的办法。。。反向遍历,加上相应的单位,然后用replace替换掉多余的零以及对应的单位就可以了。。。。

然后这一题计算秒的,昨天前前后后也想了几个小时,最后才想出来这个。。。。

不过哥们,你也睡这么晚?
作者: 左脑想你    时间: 2014-9-2 13:56
date类来实现
作者: noiary    时间: 2014-9-2 14:19
本帖最后由 noiary 于 2014-9-2 14:22 编辑
  1. /*
  2. 键盘输入6,打印6秒;
  3. 键盘输入60,打印1分;
  4. 键盘输入66,打印1分6秒;
  5. 键盘输入666,打印11分6秒;
  6. 键盘输入3601,打印1小时1秒
  7. */

  8. public class Test {

  9.         public static final int SECOND_OF_MINUTE = 60;//1分钟的秒数
  10.         public static final int SECOND_OF_HOUR = 3600;//1小时的秒数
  11.         public static final int SECOND_OF_DAY = 86400;//1天的秒数
  12.         public static final int SECOND_OF_MONTH = 2592000;//1个月的秒数
  13.         /*
  14.          方法太原始,下面以此类推就不写了.
  15.          public static final int SECOND_OF_YEAR = 31536000;//1年的秒数
  16.         */

  17.         /*
  18.          主控制程序
  19.         */
  20.         public static void main(String[] args) {

  21.                 int time = 2505601;
  22.                
  23.                 System.out.println(select(time));
  24.         }

  25.         /*
  26.         根据time取值范围选择打印格式
  27.         */
  28.         static String select(int time) {
  29.                
  30.                 String str;
  31.                
  32.                 if(time < SECOND_OF_MINUTE)
  33.                         str = time + "秒";

  34.                 else if(time >= SECOND_OF_MINUTE && time < SECOND_OF_HOUR)
  35.                         str =  dealMinute(time);
  36.                        
  37.                 else if(time >= SECOND_OF_HOUR && time < SECOND_OF_DAY)
  38.                         str = dealHour(time);
  39.                        
  40.                 else if(time >= SECOND_OF_DAY && time < SECOND_OF_MONTH)
  41.                         str = dealDay(time);
  42.                        
  43.                 else if(time >= SECOND_OF_DAY)
  44.                         str = "目测超过"+ SECOND_OF_MONTH +"秒,无法计算 T_T.";
  45.                        
  46.                 else
  47.                         str = "我也不知道哪里出错了...";
  48.                        
  49.                 return str;
  50.         }

  51.        
  52.                 /*
  53.                  xx分钟格式
  54.                 */
  55.                 static String dealMinute(int time) {
  56.                         int mod = time % SECOND_OF_MINUTE;
  57.                         int minute = (time - mod)/SECOND_OF_MINUTE;
  58.                         if(mod == 0)
  59.                                 return minute + "分";
  60.                         else
  61.                                 return minute + "分" + mod + "秒";
  62.                 }
  63.                
  64.                
  65.                 /*
  66.                  xx小时格式
  67.                 */
  68.                 static String dealHour(int time) {
  69.                
  70.                         int mod = time % SECOND_OF_HOUR;
  71.                         int hour = (time-mod)/SECOND_OF_HOUR;
  72.                         if(mod == 0)
  73.                                 return hour + "小时";
  74.                         else
  75.                                 return hour + "小时" + select(mod);
  76.                 }
  77.                
  78.                
  79.                 /*
  80.                  xx天格式
  81.                 */
  82.                 static String dealDay(int time) {
  83.                        
  84.                         int mod = time % SECOND_OF_DAY;
  85.                         int day = (time-mod)/SECOND_OF_DAY;
  86.                         if(mod == 0)
  87.                                 return day + "天";
  88.                         else
  89.                                 return day + "天" + select(mod);
  90.                 }
  91.                
  92. }
复制代码
你说我容易嘛~~~
作者: Java黑马    时间: 2014-9-2 14:55
这是基础测试题吧,我也做过,把我的附上

package com.itheima;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test3 {

        /**
         * 第三题    从键盘接受一个数字,打印该数字表示的时间,最大单位到天,例如:
                         *键盘输入6,打印6秒;
                         *键盘输入60,打印1分;
                         *键盘输入66,打印1分6秒;
                         *键盘输入666,打印11分6秒;
                         *键盘输入3601,打印1小时1秒*
                *思路:从键盘录入数据源是键盘,读取流为System.in
                *          为了提高效率要用到BufferedReader,
                *         目的源为屏幕,直接打印。
                *输入的必须是数字,而且不能是负数,需要正则表达式。
                *根据输入的数字大小进行时、分、秒的换算
                *步骤:1、创建键盘读取流
                *           2、正则表达式,限制输入的内容
                *           3、对输入的数字进行判断及换算。
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                BufferedReader bd=null;
                try{
                        bd=new BufferedReader(new InputStreamReader(System.in));//创建高效读取流

                        String line=null;
                        String regex="\\d+";//正则表达式,对键盘输入进行筛选
                        while((line=bd.readLine())!=null){
                                if(line.equals("over")){
                                        break;
                                }
                                int num=Integer.parseInt(line);//将读取流转换为int类型
                                if(line.matches(regex))
                                {
                                        if(num<60)//小于60秒直接打印
                                                {
                                                        System.out.println(line+"秒");
                                                }
                                        if(num>=60 & num<3600)//大于等于60小于一小时,要转换成分钟
                                                {
                                                        int minutes=num/60;
                                                        int second=num-minutes*60;
                                                        System.out.println(minutes+"分"+second+"秒");
                                                }
                                        if(num>3600)//大于3600,要转换成小时
                                                {
                                                        int hours=num/3600;
                                                        int minutes=(num-hours*3600)/60;
                                                        int second=num-hours*3600-minutes*60;
                                                        System.out.println(hours+"时"+minutes+"分"+second+"秒");
                                                }
                                }
                                else
                                {
                                        System.out.println("您输入的格式不正确,请输入数字");
                                }
                }
                }catch(Exception e){
                                e.printStackTrace();
                }finally{
                        try {
                                bd.close();
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
        }
}

作者: 大成哥    时间: 2014-9-2 15:08
你已经被录取了?哪一期的?
作者: 烟海    时间: 2014-9-2 17:25
大成哥 发表于 2014-9-2 15:08
你已经被录取了?哪一期的?

44期。。9。9的。。。。
作者: 安茹黑马    时间: 2014-9-2 18:02
楼主写的这个程序很精简,我当初也做了这题,我用了一大堆的if   和else  if  ,还是你这个看起来比较清爽
作者: 孤鸢    时间: 2014-9-2 18:13
厉害,思想凝结后就是简洁
作者: 安茹黑马    时间: 2014-9-2 18:36
楼主我想问一下,你12行应该是time%86400吧?还有第15行,那个if是干嘛用的?我不知道这句话有什么意思,特意来请教一下楼主
作者: 安茹黑马    时间: 2014-9-2 18:47
fantacyleo 发表于 2014-9-2 02:42
思路差不多就是这样了,跟把一个整数转为中文表示(如1002转为一千零二)是类似的,我是想不出再改进的办法 ...

哥们,你这时间复杂度是怎么算出来的呀?
作者: 烟海    时间: 2014-9-2 19:12
安茹黑马 发表于 2014-9-2 18:36
楼主我想问一下,你12行应该是time%86400吧?还有第15行,那个if是干嘛用的?我不知道这句话有什么意思,特 ...

是%24 ,因为是天数转成小时。。。。%86400就出问题了。。。你自己测试下。。。
15行的if ,是为了判断0分,0时的情况。。。

假如1天整,我不能显示1天0时0分吧 ?
作者: 烟海    时间: 2014-9-2 19:13
左脑想你 发表于 2014-9-2 13:56
date类来实现

求告知细节。。如何更简单的实现这一个需求?
作者: 烟海    时间: 2014-9-2 19:14
noiary 发表于 2014-9-2 14:19
你说我容易嘛~~~

这代码写的也太复杂了吧 。。虽然确实考虑到了各种情况。。。考虑到了年的情况。。
作者: 烟海    时间: 2014-9-2 19:16
安茹黑马 发表于 2014-9-2 18:02
楼主写的这个程序很精简,我当初也做了这题,我用了一大堆的if   和else  if  ,还是你这个看起来比较清爽 ...

很早就看到这一题,就想写一写了。。
只是一直没写,昨天一个同学遇到这一题。。我想想,觉得再重新写写,练练手。。
前前后后花了两个小时,写了两遍代码。。
第二遍,精简成这个样子。。。
作者: 安茹黑马    时间: 2014-9-2 19:35
烟海 发表于 2014-9-2 19:12
是%24 ,因为是天数转成小时。。。。%86400就出问题了。。。你自己测试下。。。
15行的if ,是为了判断0分 ...

我测试了好几遍啊,%86400没有任何问题啊,反倒是改成24会出错的,还有如果是1天整的话,因为for里面要判断条件的,time要大于0的,所以time如果等于0的话,根本就进不了循环体内啊,难道是我想错了??我有点怀疑我自己了
作者: lhtwm1    时间: 2014-9-2 19:48
这个必须收藏啊
作者: 烟海    时间: 2014-9-2 19:57
安茹黑马 发表于 2014-9-2 19:35
我测试了好几遍啊,%86400没有任何问题啊,反倒是改成24会出错的,还有如果是1天整的话,因为for里面要判 ...

确实需要%86400 ,这个地方测试的时候没注意,所以这地方判断出错误了。。
作者: 烟海    时间: 2014-9-2 19:58
安茹黑马 发表于 2014-9-2 19:35
我测试了好几遍啊,%86400没有任何问题啊,反倒是改成24会出错的,还有如果是1天整的话,因为for里面要判 ...

单纯time = 0 ,这个情况确实没考虑到。。。

但是自然情况下,会出现0秒的情况吗?

还需要多长时间能好?还需要1秒,还需要0秒??

不过也算是这个情况没考虑。
作者: 28了还能学吗    时间: 2014-9-2 20:41
不明觉厉
作者: noiary    时间: 2014-9-2 21:24
烟海 发表于 2014-9-2 19:14
这代码写的也太复杂了吧 。。虽然确实考虑到了各种情况。。。考虑到了年的情况。。 ...

哈哈哈 我只会这个啊 ,  你写的那些什么System.in  什么io流 DATE神马的  我都不会{:3_57:}
作者: 烟海    时间: 2014-9-2 22:10
noiary 发表于 2014-9-2 21:24
哈哈哈 我只会这个啊 ,  你写的那些什么System.in  什么io流 DATE神马的  我都不会 ...

但是这里面并没有用io流和data 。。。都是最简单的代码。。
作者: 小子考驾照    时间: 2014-9-2 22:37
原来这样啊,不错不错
作者: noiary    时间: 2014-9-2 23:29
烟海 发表于 2014-9-2 22:10
但是这里面并没有用io流和data 。。。都是最简单的代码。。

那我也没看懂- -. 还没学到那里


刚刚看完异常,准备明天学package
作者: a6511631    时间: 2014-9-3 16:07
烟海 发表于 2014-9-2 11:45
那个整数转出中文显示。。。比这个还复杂挺多。。。
那一题,困扰了我将近2天的时间。。最后才用最笨的方 ...

哈,只是为了达到目的的话,我倒是写的飞快。不过没有你简洁,写的挺好的
作者: 大成哥    时间: 2014-9-5 09:20
烟海 发表于 2014-9-2 17:25
44期。。9。9的。。。。

哦哦 加油!一般录取分几批?有时间限制么
作者: dftgg    时间: 2014-9-5 12:47
public class Test1 {
       
        public static int min = 60;  //1分=60秒
        public static int hour = min*60;  //1时=60分
        public static int day = hour*24; //1天=24时

        public static void main(String[] args) {
               
                        //实例化scanner
                    Scanner scan = new Scanner(System.in);
                   
                    //实例化StringBuilder,用于存储元素
                    StringBuilder sbu = new StringBuilder();
                   
                    System.out.print("请输入一个数字:");
                    //接收键盘录入,接收一个int型数字
                    int num = scan.nextInt();
           
                                    if(num/day != 0) {  //去除0
                                           
                                            sbu.append((num/day + "天"));
                                    }
                      
                        num = num%day;
                        if (num/hour != 0){
                               
                                sbu.append((num/hour + "小时"));
                        }
                        
                        num = num%hour;
                        if (num/min != 0) {
                               
                                sbu.append((num/min + "分"));
                        }
                        
                        num = num%min;
                        if (num%min != 0) {
                               
                                sbu.append(num + "秒");
                        }
                        //输出结果
                        System.out.println(sbu.toString());
                   
        }

}
作者: 烟海    时间: 2014-9-7 00:33
大成哥 发表于 2014-9-5 09:20
哦哦 加油!一般录取分几批?有时间限制么

正常是三批录取。。。最近几期都是两批录取。。。。。

建议赶得上第一批录取。。确实会简单很多。。
作者: 大成哥    时间: 2014-9-7 00:55
烟海 发表于 2014-9-7 00:33
正常是三批录取。。。最近几期都是两批录取。。。。。

建议赶得上第一批录取。。确实会简单很多。。 ...

额……9月24的要是14好左右申请的话 是不是就第二三批了?
作者: 许愿じ☆VE杰    时间: 2014-9-7 07:57
嗯,学习了
作者: 李天富    时间: 2014-9-7 12:00
本帖最后由 李天富 于 2014-9-7 12:11 编辑
  1. import java.util.*;
  2. class  timetest
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 int time = new Scanner(System.in).nextInt();
  7.                 transTime(time);
  8.         }
  9.         public static void transTime(int num)
  10.         {
  11.                 String[] unit={"天","时","分","秒"};
  12.                 int[] time=new int[4];
  13.                 int temp=0;
  14.                 time[0]=num/86400;
  15.                 temp=num%86400;
  16.                 time[1]=temp/3600;
  17.                 temp=temp%3600;
  18.                 time[2]=temp/60;
  19.                 time[3]=temp%60;
  20.                 for (int i=0;i<4 ;i++ )
  21.                 {
  22.                         if(i!=3&&time[i]==0)
  23.                                 continue;
  24.                         System.out.print(time[i]+unit[i]);
  25.                 }
  26.         }
  27. }
复制代码
简单写了下,就是不知道对于java来说,条件判断和做除法,哪个更为简洁。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2