• Java,Hello World,《算法》环境搭建中的问题,用 cmd 和 IntelliJ Idea 分别编译和运行 Java 程序


    ▶ IntelliJ idea 下载和安装(http://www.jetbrains.com/idea/)

    ▶ 新建项目(如图),注意选择 SDK 类型和位置

    ● 在 src 目录中新建一个 Package,在该 Package 中新建一个 class,在编辑器中写该类的一个函数(主函数)如图,点击右上角锤子可以 build,或者在 build 和 run 选项卡中选择相应选项

    ● 执行结果

    ▶ 尝试运行了书中的一个代码(二分搜索与白名单),发现环境配置过程中有很多问题,姑且先把成功了的过程写在这里,仅供参考。

    ● 工作目录为 "testJava",文件目录如下,IntelliJ Idea 中建立了包 package01 和其中的一个类 class01.java,源文件放在其中(原始代码如下,大意是输入白名单文件和待筛查文件,输出白名单中不存在的值)。自动编译生成的文件是 class01.class。输入白名单数据 tinyW.txt,待筛查文件 tinyT.txt。

    D:CODEJAVATESTJAVA
    │  testJava.iml
    │  
    ├─.idea
    │      misc.xml
    │      modules.xml
    │      workspace.xml
    │      
    ├─out
    │  └─production
    │      └─testJava
    │          └─package01
    │                  class01.class
    │                  
    └─src
        └─package01
                class01.java
     1 package package01;
     2 
     3 import java.util.Arrays;
     4 
     5 import edu.princeton.cs.algs4.StdIn;
     6 import edu.princeton.cs.algs4.StdOut;
     7 import edu.princeton.cs.algs4.In;
     8 
     9 public class class01
    10 {
    11     private class01() {}
    12 
    13     public static int indexOf(int[] a, int key)
    14     {
    15         int lo = 0, hi = a.length - 1;
    16         while (lo <= hi)
    17         {
    18             int mid = lo + (hi - lo) / 2;
    19             if      (key < a[mid]) hi = mid - 1;
    20             else if (key > a[mid]) lo = mid + 1;
    21             else return mid;
    22         }
    23         return -1;
    24     }
    25 
    26     @Deprecated
    27     public static int rank(int key, int[] a
    28     {
    29         return indexOf(a, key);
    30     }
    31 
    32     public static void main(String[] args)
    33     {
    34         In in = new In(args[0]);
    35         int[] whitelist = in.readAllInts();
    36 
    37         Arrays.sort(whitelist);
    38 
    39         while (!StdIn.isEmpty())
    40         {
    41             int key = StdIn.readInt();
    42             if (class01.indexOf(whitelist, key) == -1)
    43                 StdOut.println(key);
    44         }
    45     }
    46 }

    ● 前提工作:JDK 版本和 JRE 版本要对应(https://www.oracle.com/technetwork/java/javase/downloads/index.html),否则会能编译不能运行,报错为 UnsupportedClassVersionError;安装教材附带的类库 algs4(https://algs4.cs.princeton.edu/code/,拖到中间一些的部分),需要管理员权限运行,会自动下载和安装到用户目录,设置环境变量。相关链接(https://blog.csdn.net/fsx892512592/article/details/6038448,https://blog.csdn.net/u014629433/article/details/51593164,https://blog.csdn.net/u011240877/article/details/52457904)

    ● 使用命令行进行操作:将输入文件 tinyW.txt 和 tinyT.txt 放到 src 目录下,如图所示。这里有若干可以说的事情:

       ① 设置环境变量 CLASSPATH 为 "." 以及 algs4.jar 的绝对路径,可以在我的电脑的属性里添加,也可以在命令行里临时添加,还可以在 javac 命令中以选项的方式添加;有说法认为需要附上当前目录 ".",我测试中有的代码需要加,有的代码不需要,以防万一还是加上吧。如果不添加环境变量,则编译报错 "程序包edu.princeton.cs.algs4不存在" 以及后续的 "找不到符号XXX"(程序用到了 algs4 中的 In,StdIn,StdOut 等方法),如下图所示。相关链接(https://blog.csdn.net/skyebefreeman/article/details/56495637)

    D:CodeJava	estJavasrcpackage01>javac class01.java      // 不添加环境变变量的编译
    class01.java:5: 错误: 程序包edu.princeton.cs.algs4不存在
    import edu.princeton.cs.algs4.StdIn;
                                 ^
    class01.java:6: 错误: 程序包edu.princeton.cs.algs4不存在
    import edu.princeton.cs.algs4.StdOut;
                                 ^
    class01.java:7: 错误: 程序包edu.princeton.cs.algs4不存在
    import edu.princeton.cs.algs4.In;
                                 ^
    class01.java:34: 错误: 找不到符号
            In in = new In(args[0]);
            ^
      符号:   类 In
      位置: 类 class01
    class01.java:34: 错误: 找不到符号
            In in = new In(args[0]);
                        ^
      符号:   类 In
      位置: 类 class01
    class01.java:39: 错误: 找不到符号
            while (!StdIn.isEmpty())
                    ^
      符号:   变量 StdIn
      位置: 类 class01
    class01.java:41: 错误: 找不到符号
                int key = StdIn.readInt();
                          ^
      符号:   变量 StdIn
      位置: 类 class01
    class01.java:43: 错误: 找不到符号
                    StdOut.println(key);
                    ^
      符号:   变量 StdOut
      位置: 类 class01
    8 个错误

      ② 代码首行写了包名,运行时需要退到含有完整包名那一层目录再运行。实测代码中不加包名(把源代码第一行注释掉)仍能正确编译,但是运行时会出现下面的效果,总之都无法加载主类(注意是两种错误)。相关链接(https://www.zhihu.com/question/36537093,http://www.cnblogs.com/wangxiaoha/p/6293340.html,https://blog.csdn.net/codefellow/article/details/76601885,https://blog.csdn.net/u014427391/article/details/79743318,https://www.cnblogs.com/xyhz0310/p/6803950.html)

    D:CodeJava	estJavasrcpackage01>java class01.class tinyW.txt < tinyT.txt            // 内层执行,代码无包名
    错误: 找不到或无法加载主类 class01.class
    原因: java.lang.ClassNotFoundException: class01.class
    
    D:CodeJava	estJavasrcpackage01>java package01.class01.class tinyW.txt < tinyT.txt  // 内层执行,代码有包名
    错误: 找不到或无法加载主类 package01.class01.class
    原因: java.lang.ClassNotFoundException: package01.class01.class
    
    D:CodeJava	estJavasrcpackage01>cd ..
    
    D:CodeJava	estJavasrc>java class01 tinyW.txt < tinyT.txt                            // 外层执行,代码无包名
    错误: 找不到或无法加载主类 class01
    原因: java.lang.ClassNotFoundException: class01
    
    D:CodeJava	estJavasrc>java package01.class01 tinyW.txt < tinyT.txt                  // 外层执行,代码有包名
    错误: 找不到或无法加载主类 package01.class01
    原因: java.lang.NoClassDefFoundError: class01 (wrong name: package01/class01)

      ③ 同时使用输入文件和重定向将两个文件喂给程序,输出了正确的结果,这里没有太大问题。

    ● Idea 中先准备库路径(类似添加环境变量):File → Project Structure → Modules → 右边的 "+" → JARs or directories → 选择上面安装的 algs4.jar(C:UserUsernamealgs4algs4.jar)→ 左边 □ 不清楚是否要勾上,右边的 Compile / Run / Test / Provided 不清楚要选哪个,姑且选了 compile。相关链接(https://blog.csdn.net/t95921/article/details/53585225)

    ● 点击原谅锤编译,生成字节码文件在 out 目录下,缺少库则会报错,缺少包名仍能正确编译

    ● 设置运行时配置(原谅锤右边的框)如下图。写了主类(好像必填),输入参数(注意输入文件的相对路径是相对工作目录而言的,不要像上面 cmd 方式那样放进 src 或 out 目录),工作目录,类路径,其他没有改动

    ● 至此,程序能够正常开始运行,但还有点问题。

      ① 直接运行会发现程序会卡在 while (!StdIn.isEmpty()) 。理由是此时 Std 中内容不明,反正找不到可以作为输入结束的字符,所以会一直挂住。用 step into 去看会进入 StdIn.java ,如下所示,卡在 return 这一行上。需要运行时(卡住以后)在 运行窗口中手动补充结尾符 "^D"(Ecplise 或 Linux 环境中可能是 "^Z"),解决问题。相关链接(https://www.zhihu.com/question/62001393,https://blog,.csdn.net/dmbjzhh/article/details/80525487,https://stackoverflow.com/questions/18437181/simulate-input-from-stdin-when-running-a-program-in-intellij,https://stackoverflow.com/questions/34972425/executing-nothing-java-project-in-intellij-idea,https://stackoverflow.com/questions/14991760/stdin-isempty-java,http://www.1point3acres.com/bbs/thread-2463-1-1.html)

     1 public final class StdIn
     2 {
     3     ...
     4     
     5     public static boolean isEmpty()
     6     {
     7         return !scanner.hasNext();
     8     }
     9 
    10     ...
    11 }

      ② 源代码使用运行参数是 "tinyW.txt < tinyT.txt",尝试打印输入参数,发现 arg[0] = "tinyW.txt";arg[1] = "<";arg[2] = "tinyT.txt",理论上应该没有问题(主函数自行处理 "<" 后的重定向文件参数),不清楚原因,不能自动完成输入。

      ③ 另一种解决方案,最后我把代码改成如下所示(不耐烦用 StdIn 和重定向输入,而是手工读取和检测边界),运行参数为 "tinyW.txt tinyT.txt",能够正确输出结果。本章下一篇博客才成功使用教材自带的 StdIn / StdOut 等方法,可以作为参考。

     1 package package01;
     2 
     3 import java.util.Arrays;
     4 
     5 import edu.princeton.cs.algs4.StdOut;
     6 import edu.princeton.cs.algs4.In;
     7 
     8 public class class01
     9 {
    10     private class01() {}
    11 
    12     public static int indexOf(int[] a, int key)
    13     {
    14         int lo = 0, hi = a.length - 1;
    15         while (lo <= hi)
    16         {
    17             int mid = lo + (hi - lo) / 2;
    18             if      (key < a[mid]) hi = mid - 1;
    19             else if (key > a[mid]) lo = mid + 1;
    20             else return mid;
    21         }
    22         return -1;
    23     }
    24 
    25     @Deprecated
    26     public static int rank(int key, int[] a)
    27     {
    28         return indexOf(a, key);
    29     }
    30 
    31     public static void main(String[] args)
    32     {
    33         In in = new In(args[0]);
    34         In in2 = new In(args[1]);
    35 
    36         int[] whitelist = in.readAllInts();
    37         int[] test = in2.readAllInts();
    38 
    39         Arrays.sort(whitelist);
    40         Arrays.sort(test);
    41         
    42         for(int i=0;i<test.length;i++)
    43         {
    44             int key = test[i];
    45             if (class01.indexOf(whitelist, key) == -1)
    46                 StdOut.println(key);
    47         }
    48     }
    49 }

    ▶ 其他问题

    ● 修改项目的类名,要注意类文件名和代码中用到类名的地方都要改掉

    ● 命令行 javac 默认支持 ASCII 编码,代码里有中文注释要去掉,或者在 javac 命令中使用选项 -encoding UTF-8 来改变使用的编码类型。

  • 相关阅读:
    非常不错的学习网站——技术胖
    Vue中使用mescroll.js实现下拉刷新
    2020.10.07【NOIP提高A组】模拟
    2020.10.06【NOIP提高A组】模拟 总结
    2020.09.19【NOIP提高A组】模拟
    2020.09.12【NOIP提高A组】模拟
    GMOJ 4417. 【HNOI2016模拟4.1】神奇的字符串 题解
    上下界网络流学习笔记
    GMOJ 3571. 【GDKOI2014】内存分配 题解
    [模板]人工栈
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9721668.html
Copyright © 2020-2023  润新知