栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

解决填字游戏

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

解决填字游戏

您拥有的基本想法非常明智:

  1. 识别板上的插槽。
  2. 尝试每个适合每个单词的插槽。
  3. 如果每个插槽都可以无冲突地填满,那就解决了。

这是一个很棒的计划。下一步是将其转换为设计。对于这样的小程序,我们可以直接使用伪代码。如其他答案所述,其要点是递归:

1  Draw a slot from the slot pool.2     If slot pool is empty (all slots filled), stop solving.3  For each word with correct length:4     If part of the slot is filled, check conflict.5        If the word does not fit, continue the loop to next word.      // No conflict6     Fill the slot with the word.      // Try next slot (down a level)7     Recur from step 1.8     If the recur found no solution, revert (take the word back) and try next.   // None of them works9  If no words yield a solution, an upper level need to try another word.   Revert (put the slot back) and go back.

以下是一个简短但完整的示例,我根据您的要求进行了整理。

剥猫的方法不止一种。我的代码交换了步骤1和2,并在一个填充循环中组合了步骤4至6。

关键点:

  • 使用格式化程序使代码适合您的样式。
  • 2D板以行优先顺序存储在线性字符数组中。
  • 这使该板可以
    clone()
    由arraycopy保存和恢复。
  • 创建后,将在两个方向的两个通道中扫描电路板上的插槽。
  • 这两个插槽列表由同一循环解决,主要区别在于插槽的填充方式。
  • 此时将显示递归过程,因此您可以查看其工作方式。
  • 有许多假设。没有单个字母槽,所有单词在相同情况下,板均正确等。
  • 耐心一点。了解新事物并给自己时间去吸收它。

资源:

import java.awt.Point;import java.util.*;import java.util.function.BiFunction;import java.util.function.Supplier;import java.util.stream.Stream;public class Crossword {   public static void main ( String[] args ) {      new Crossword( Arrays.asList( "5 4 4n#_#_#n_____n#_##_n#_##_ntunanmusicncannhi".split( "n" ) ) );      new Crossword( Arrays.asList( "6 6 4n##_###n#____#n___#__n#_##_#n#____#n##_###nnicenpainnpalnid".split( "n" ) ) );   }   private final int height, width; // Board size   private final char[] board; // Current board state.  _ is unfilled.  # is blocked.  other characters are filled.   private final Set<String> words; // List of words   private final Map<Point, Integer> vertical = new HashMap<>(), horizontal = new HashMap<>();  // Vertical and horizontal slots   private String indent = ""; // For formatting log   private void log ( String message, Object... args ) { System.out.println( indent + String.format( message, args ) ); }   private Crossword ( List<String> lines ) {      // Parse input data      final int[] sizes = Stream.of( lines.get(0).split( "\s+" ) ).mapToInt( Integer::parseInt ).toArray();      width = sizes[0];  height = sizes[1];      board = String.join( "", lines.subList( 1, height+1 ) ).toCharArray();      words = new HashSet<>( lines.subList( height+1, lines.size() ) );      // Find horizontal slots then vertical slots      for ( int y = 0, size ; y < height ; y++ )         for ( int x = 0 ; x < width-1 ; x++ ) if ( isSpace( x, y ) && isSpace( x+1, y ) ) {    for ( size = 2 ; x+size < width && isSpace( x+size, y ) ; size++ ); // Find slot size    horizontal.put( new Point( x, y ), size );    x += size; // Skip past this horizontal slot }      for ( int x = 0, size ; x < width ; x++ )         for ( int y = 0 ; y < height-1 ; y++ ) if ( isSpace( x, y ) && isSpace( x, y+1 ) ) {    for ( size = 2 ; y+size < height && isSpace( x, y+size ) ; size++ ); // Find slot size    vertical.put( new Point( x, y ), size );    y += size; // Skip past this vertical slot }      log( "A " + width + "x" + height + " board, " + vertical.size() + " vertical, " + horizontal.size() + " horizontal." );      // Solve the crossword, horizontal first then vertical      final boolean solved = solveHorizontal();      // Show board, either fully filled or totally empty.      for ( int i = 0 ; i < board.length ; i++ ) {         if ( i % width == 0 ) System.out.println();         System.out.print( board[i] );      }      System.out.println( solved ? "n" : "nNo solution foundn" );   }   // Helper functions to check or set board cell   private char get ( int x, int y ) { return board[ y * width + x ]; }   private void set ( int x, int y, char character ) { board[ y * width + x ] = character; }   private boolean isSpace ( int x, int y ) { return get( x, y ) == '_'; }   // Fit all horizontal slots, when success move to solve vertical.   private boolean solveHorizontal () {      return solve( horizontal, this::fitHorizontal, "horizontally", this::solveVertical );   }   // Fit all vertical slots, report success when done   private boolean solveVertical () {      return solve( vertical, this::fitVertical, "vertically", () -> true );   }   // Recur each slot, try every word in a loop.  When all slots of this kind are filled successfully, run next stage.   private boolean solve ( Map<Point, Integer> slot, BiFunction<Point, String, Boolean> fill, String dir, Supplier<Boolean> next ) {      if ( slot.isEmpty() ) return next.get(); // If finished, move to next stage.      final Point pos = slot.keySet().iterator().next();      final int size = slot.remove( pos );      final char[] state = board.clone();             indent += "  ";      for ( String word : words ) {         if ( word.length() != size ) continue;            log( "Trying %s %s at %d,%d", word, dir, pos.x, pos.y );         if ( fill.apply( pos, word ) && solve( slot, fill, dir, next ) ) return true;             log( "%s failed %s at %d,%d", word, dir, pos.x, pos.y );         System.arraycopy( state, 0, board, 0, board.length );      }      indent = indent.substring( 0, indent.length() - 2 );      slot.put( pos, size );      return false;   }   // Try fit a word to a slot.  Return false if there is a conflict.   private boolean fitHorizontal ( Point pos, String word ) {      final int x = pos.x, y = pos.y;      for ( int i = 0 ; i < word.length() ; i++ ) {         if ( ! isSpace( x+i, y ) && get( x+i, y ) != word.charAt( i ) ) return false; // Conflict         set( x+i, y, word.charAt( i ) );      }      return true;   }   private boolean fitVertical ( Point pos, String word ) {      final int x = pos.x, y = pos.y;      for ( int i = 0 ; i < word.length() ; i++ ) {         if ( ! isSpace( x, y+i ) && get( x, y+i ) != word.charAt( i ) ) return false; // Conflict         set( x, y+i, word.charAt( i ) );      }      return true;   }}

练习:您可以将递归重写为迭代。更快,并且可以支持更大的板。一旦完成,它可以转换为多线程并运行得更快。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/437274.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号