最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)的按照順時(shí)針或逆時(shí)針?lè)较蜉敵鲆粋€(gè)數(shù)字矩陣功能示例

 更新時(shí)間:2018年01月10日 12:15:17   作者:捏造的信仰  
這篇文章主要介紹了Java實(shí)現(xiàn)的按照順時(shí)針或逆時(shí)針?lè)较蜉敵鲆粋€(gè)數(shù)字矩陣功能,涉及java基于數(shù)組遍歷、運(yùn)算的矩陣操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Java實(shí)現(xiàn)的按照順時(shí)針或逆時(shí)針?lè)较蜉敵鲆粋€(gè)數(shù)字矩陣功能。分享給大家供大家參考,具體如下:

題目:按照指定的長(zhǎng)寬和輸出方向,從外向內(nèi)打印一個(gè)從 1 開(kāi)始的數(shù)字矩陣,矩陣的開(kāi)始位置在左上角。如下圖

代碼及注釋如下:

public class NumberMatrix {
  public static void main(String[] args) {
    int width = 25;
    int height = 12;
    boolean clockwise = false;
    System.out.println("腳本之家測(cè)試結(jié)果:");
    outputMatrix(width, height, clockwise);
  }
  /**
   * 按照指定的長(zhǎng)寬和輸出方向,從外向內(nèi)打印一個(gè)從 1 開(kāi)始的數(shù)字矩陣,矩陣的開(kāi)始位置在左上角。
   *
   * @param width   矩陣寬度
   * @param height  矩陣高度
   * @param clockwise 是否是順時(shí)針?lè)较?
   */
  private static void outputMatrix(int width, int height, boolean clockwise) {
    // 首先判斷最大數(shù)字的位數(shù),以決定輸出如何對(duì)齊
    int numLength = (int) Math.log10(width * height) + 1;
    // 決定輸出的格式(最大位數(shù) + 1個(gè)空格)
    String format = "%" + (numLength + 1) + "d";
    // 定義要輸出的二維數(shù)組,注意維度是從高到低的
    // 此時(shí) matrix 中所有元素的值都是 0
    int[][] matrix = new int[height][width];
    // 定義一個(gè)位置指針和一個(gè)計(jì)數(shù)器,位置指針進(jìn)行移動(dòng),而計(jì)數(shù)器負(fù)責(zé)遞增,遞增后的數(shù)字
    // 被填充進(jìn)矩陣,當(dāng) width * height 個(gè)數(shù)字填充完畢,這個(gè)矩陣就完成了。
    // 注意這里位置指針的第一個(gè)元素對(duì)應(yīng) matrix 的第一個(gè)維度 y,第二個(gè)元素對(duì)應(yīng)第二個(gè)維度 x。
    int[] pointer = {0, 0};
    int counter = 1;
    // 定義當(dāng)前移動(dòng)的方向:1、2、3、4 分別表示上、右、下、左。
    // 順時(shí)針的起始方向?yàn)橛遥鏁r(shí)針的起始方向?yàn)橄隆?
    int direction = clockwise ? 2 : 3;
    // 開(kāi)始循環(huán)填充,每個(gè)填充分為三步
    for (int i = 1, max = width * height; i <= max; i++) {
      // 1. 填充內(nèi)容
      int y = pointer[0];
      int x = pointer[1];
      matrix[y][x] = counter;
      // 2. 計(jì)數(shù)器自增
      counter += 1;
      // 3. 移動(dòng)到下一個(gè)位置,因?yàn)檫@地方比較復(fù)雜,所以開(kāi)個(gè)方法實(shí)現(xiàn)
      direction = move(matrix, width, height, pointer, direction, clockwise);
    }
    // 矩陣填充完畢,按照正常的方式循環(huán)輸出即可
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        System.out.printf(format, matrix[y][x]);
      }
      System.out.println(); // 完成一行后輸出換行
    }
  }
  /**
   * 在矩陣中移動(dòng)
   *
   * @param matrix  矩陣,用于判斷前進(jìn)方向的下一個(gè)位置是否已經(jīng)填充了數(shù)字,如果是則轉(zhuǎn)向
   * @param width   矩陣的寬
   * @param height  矩陣的高
   * @param pointer  指針的當(dāng)前位置。調(diào)用本方法后里面的值會(huì)改變,除非方法返回 0
   * @param direction 指針當(dāng)前移動(dòng)的方向
   * @param clockwise 是否是要按順時(shí)針?lè)较蜣D(zhuǎn)向
   *
   * @return 移動(dòng)后的新方向(與原來(lái)的方向可能相同也可能不同)。如果無(wú)法再繼續(xù)移動(dòng),則返回 0
   */
  private static int move(int[][] matrix, int width, int height, int[] pointer, int direction, boolean clockwise) {
    // 先嘗試按照原來(lái)的方向移動(dòng)到 newPointer
    int[] newPointer = moveDirectly(pointer, direction);
    // 檢查 newPointer 是否合法,如果合法則將其賦值給 pointer 并保持原來(lái)的方向,方法完成
    if (isValid(newPointer, matrix, width, height)) {
      System.arraycopy(newPointer, 0, pointer, 0, 2);
      return direction;
    }
    // 進(jìn)行轉(zhuǎn)向,重新從 pointer 朝新的方向移動(dòng)
    direction = turn(direction, clockwise);
    newPointer = moveDirectly(pointer, direction);
    // 檢查 newPointer 是否合法(同前面一樣)
    if (isValid(newPointer, matrix, width, height)) {
      System.arraycopy(newPointer, 0, pointer, 0, 2);
      return direction;
    }
    // 既無(wú)法前進(jìn)也無(wú)法轉(zhuǎn)向,那么無(wú)法繼續(xù)移動(dòng)。
    return 0;
  }
  // 判斷矩陣中指定的位置是否可以填充
  private static boolean isValid(int[] newPointer, int[][] matrix, int width, int height) {
    // 位置不能超出矩陣范圍
    if (newPointer[0] >= height
        || newPointer[0] < 0
        || newPointer[1] >= width
        || newPointer[1] < 0) {
      return false;
    }
    // 位置的內(nèi)容應(yīng)該為空
    if (matrix[newPointer[0]][newPointer[1]] != 0) {
      return false;
    }
    return true;
  }
  // 轉(zhuǎn)向。根據(jù)我們對(duì) direction 的定義,順時(shí)針就是 +1,逆時(shí)針就是 -1
  private static int turn(int direction, boolean clockwise) {
    int newDirection = clockwise ? direction + 1 : direction - 1;
    if (newDirection > 4) {
      newDirection = 1;
    } else if (newDirection < 1) {
      newDirection = 4;
    }
    return newDirection;
  }
  /**
   * 朝指定的方向移動(dòng),并返回新的位置
   *
   * @param pointer  當(dāng)前位置
   * @param direction 方向
   *
   * @return 新的位置
   */
  private static int[] moveDirectly(int[] pointer, int direction) {
    int y = pointer[0];
    int x = pointer[1];
    switch (direction) {
      case 1:
        return new int[]{y - 1, x};
      case 2:
        return new int[]{y, x + 1};
      case 3:
        return new int[]{y + 1, x};
      case 4:
        return new int[]{y, x - 1};
    }
    throw new IllegalArgumentException("方向不正確: " + direction);
  }
}

運(yùn)行結(jié)果:

更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Kafka中的producer攔截器與consumer攔截器詳解

    Kafka中的producer攔截器與consumer攔截器詳解

    這篇文章主要介紹了Kafka中的producer攔截器與consumer攔截器詳解,Producer 的Interceptor使得用戶(hù)在消息發(fā)送前以及Producer回調(diào)邏輯前有機(jī)會(huì)對(duì)消息做 一些定制化需求,比如修改消息等,需要的朋友可以參考下
    2023-12-12
  • java線程池使用后到底要關(guān)閉嗎

    java線程池使用后到底要關(guān)閉嗎

    這篇文章主要給大家介紹了關(guān)于java線程池使用后到底要不要關(guān)閉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 教你開(kāi)發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過(guò)程

    教你開(kāi)發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過(guò)程

    這篇文章主要介紹了開(kāi)發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過(guò)程,集成包括引入依賴(lài)配置文件及訪問(wèn)驗(yàn)證的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Java讀取其下所有文件夾與文件路徑的方法

    Java讀取其下所有文件夾與文件路徑的方法

    這篇文章主要為大家詳細(xì)介紹了Java讀取其下所有文件夾與文件路徑的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 如何查看java進(jìn)程內(nèi)存占用情況

    如何查看java進(jìn)程內(nèi)存占用情況

    這篇文章主要介紹了如何查看java進(jìn)程內(nèi)存占用情況問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java調(diào)用openoffice將office系列文檔轉(zhuǎn)換為PDF的示例方法

    java調(diào)用openoffice將office系列文檔轉(zhuǎn)換為PDF的示例方法

    本篇文章主要介紹了java使用openoffice將office系列文檔轉(zhuǎn)換為PDF的示例方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-11-11
  • SpringBoot注解篇之@Resource與@Autowired的使用區(qū)別

    SpringBoot注解篇之@Resource與@Autowired的使用區(qū)別

    @Resource 注解和 @Autowired 注解都是在 Spring Framework 中進(jìn)行依賴(lài)注入的注解,那么你知道他們有什么區(qū)別嗎,本文就來(lái)介紹一下
    2023-12-12
  • Java如何接收前端easyui?datagrid傳遞的數(shù)組參數(shù)

    Java如何接收前端easyui?datagrid傳遞的數(shù)組參數(shù)

    這篇文章分享一下怎么在easyui的datagrid刷新表格時(shí),在后端java代碼中接收datagrid傳遞的數(shù)組參數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-11-11
  • SpringBoot使用MyBatis實(shí)現(xiàn)數(shù)據(jù)的CRUD

    SpringBoot使用MyBatis實(shí)現(xiàn)數(shù)據(jù)的CRUD

    MyBatis是一個(gè)輕量級(jí)的對(duì)象關(guān)系映射(Object-Relational Mapping,ORM)框架,它允許開(kāi)發(fā)者通過(guò)編寫(xiě)SQL動(dòng)態(tài)查詢(xún)數(shù)據(jù)庫(kù),而無(wú)需顯式地操作JDBC,對(duì)于增刪改查操作,MyBatis提供了一種基于XML或注解的方式來(lái)進(jìn)行,本文介紹了SpringBoot使用MyBatis實(shí)現(xiàn)數(shù)據(jù)的CRUD
    2024-11-11
  • Java中Steam流的用法詳解

    Java中Steam流的用法詳解

    Stream是Java?8?API添加的一個(gè)新的抽象,稱(chēng)為流Stream,本文主要介紹了Java中Steam流的用法詳解,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-04-04

最新評(píng)論

绍兴县| 麻城市| 兴义市| 佳木斯市| 思南县| 东宁县| 沈阳市| 丘北县| 平顶山市| 金门县| 建水县| 石景山区| 长泰县| 马关县| 普兰店市| 云龙县| 安达市| 永修县| 罗城| 砀山县| 凤冈县| 翁源县| 祥云县| 滦南县| 仁化县| 宜阳县| 邹平县| 台州市| 宜春市| 鹰潭市| 启东市| 牡丹江市| 肃宁县| 永川市| 呼伦贝尔市| 乐昌市| 白银市| 茂名市| 沂源县| 元朗区| 曲周县|