(D卷,200分)- 找单词(Java & JS & Python&C)

题目描述

给一个字符串和一个二维字符数组,如果该字符串存在于该数组中,则按字符串的字符顺序输出字符串每个字符所在单元格的位置下标字符串,如果找不到返回字符串“N”。

1.需要按照字符串的字符组成顺序搜索,且搜索到的位置必须是相邻单元格,其中“相邻单元格”是指那些水平相邻或垂直相邻的单元格。

2.同一个单元格内的字母不允许被重复使用。

3.假定在数组中最多只存在一个可能的匹配。

输入描述

第1行为一个数字N指示二维数组在后续输入所占的行数。

第2行到第N+1行输入为一个二维大写字符数组,每行字符用半角,分割。

第N+2行为待查找的字符串,由大写字符组成。

二维数组的大小为N*N,0<N<=100。

单词长度K,0<K<1000。

输出描述

输出一个位置下标字符串,拼接格式为:第1个字符行下标+”,”+第1个字符列下标+”,”+第2个字符行下标+”,”+第2个字符列下标… +”,”+第N个字符行下标+”,”+第N个字符列下标。

用例
输入4
A,C,C,F
C,D,E,D
B,E,S,S
F,E,C,A
ACCESS
输出0,0,0,1,0,2,1,2,2,2,2,3
说明ACCESS分别对应二维数组的[0,0] [0,1] [0,2] [1,2] [2,2] [2,3]下标位置。

这个问题的核心是从二维字符数组中找到一个特定的字符串,并确定字符串中的每个字符在数组中的位置。字符在数组中必须按照字符串的顺序,并且必须是相邻的单元格。相邻的定义包括水平和垂直相邻,不能重复使用相同的单元格。

题目解析

  1. 输入解析:

    • 二维数组: 从第一行到第N+1行,每行包含N个字符。
    • 待查找的字符串: 在第N+2行给出。
  2. 目标:

    • 如果找到该字符串,返回每个字符的坐标。坐标的输出格式为 row1,col1,row2,col2,...
    • 如果找不到该字符串,返回 N
  3. 约束:

    • 查找的字符必须是相邻的,包括水平和垂直方向。
    • 单元格不能重复使用。

解题步骤

  1. 遍历二维数组:

    • 对每个单元格进行深度优先搜索 (DFS),尝试从每个单元格开始匹配字符串。
  2. 深度优先搜索 (DFS):

    • 从当前单元格出发,尝试找到字符串中的下一个字符。
    • 确保下一个字符在相邻的单元格中,并且单元格没有被重复使用。
    • 记录已找到的字符位置。
  3. 坐标记录和输出:

    • 如果匹配成功,记录路径上的坐标。
    • 如果遍历完所有可能的起点都没有找到匹配,则输出 N

 JAVA算法源码

import java.util.*;

public class WordSearch {
    
    private static final int[] ROW_DIRS = {0, 0, 1, -1}; // 右, 左, 下, 上
    private static final int[] COL_DIRS = {1, -1, 0, 0};
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        int N = Integer.parseInt(scanner.nextLine().trim());
        char[][] grid = new char[N][N];
        
        for (int i = 0; i < N; i++) {
            String[] row = scanner.nextLine().trim().split(",");
            for (int j = 0; j < N; j++) {
                grid[i][j] = row[j].charAt(0);
            }
        }
        
        String word = scanner.nextLine().trim();
        
        List<String> result = findWordInGrid(grid, N, word);
        
        if (result.isEmpty()) {
            System.out.println("N");
        } else {
            System.out.println(String.join(",", result));
        }
    }
    
    private static List<String> findWordInGrid(char[][] grid, int N, String word) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (grid[i][j] == word.charAt(0)) {
                    boolean[][] visited = new boolean[N][N];
                    List<String> path = new ArrayList<>();
                    if (search(grid, N, word, 0, i, j, visited, path)) {
                        return path;
                    }
                }
            }
        }
        return new ArrayList<>();
    }
    
    private static boolean search(char[][] grid, int N, String word, int index, int row, int col, boolean[][] visited, List<String> path) {
        if (index == word.length()) {
            return true;
        }
        
        if (row < 0 || col < 0 || row >= N || col >= N || visited[row][col] || grid[row][col] != word.charAt(index)) {
            return false;
        }
        
        visited[row][col] = true;
        path.add(row + "," + col);
        
        for (int i = 0; i < 4; i++) {
            int newRow = row + ROW_DIRS[i];
            int newCol = col + COL_DIRS[i];
            if (search(grid, N, word, index + 1, newRow, newCol, visited, path)) {
                return true;
            }
        }
        
        visited[row][col] = false;
        path.remove(path.size() - 1);
        return false;
    }
}

解释

  1. 数据输入:

    • 通过 Scanner 读取输入的二维数组和待查找的字符串。
  2. 深度优先搜索 (DFS):

    • search 方法用于递归地寻找字符串,记录路径。
  3. 路径记录:

    • path 列表记录找到的字符坐标。
  4. 输出:

    • 如果找到字符串,按要求格式化输出坐标。如果没有找到,输出 "N"

这个代码实现了从二维数组中查找字符串并返回字符位置的需求,符合题目的所有要求。


JS算法源码

function findWordInGrid(grid, word) {
    const N = grid.length;
    const directions = [
        [0, 1], // 右
        [0, -1], // 左
        [1, 0], // 下
        [-1, 0] // 上
    ];
    
    function isValid(x, y) {
        return x >= 0 && x < N && y >= 0 && y < N;
    }
    
    function search(x, y, index, visited, path) {
        if (index === word.length) {
            return true;
        }
        
        if (!isValid(x, y) || visited[x][y] || grid[x][y] !== word[index]) {
            return false;
        }
        
        visited[x][y] = true;
        path.push(`${x},${y}`);
        
        for (const [dx, dy] of directions) {
            const newX = x + dx;
            const newY = y + dy;
            if (search(newX, newY, index + 1, visited, path)) {
                return true;
            }
        }
        
        visited[x][y] = false;
        path.pop();
        return false;
    }
    
    for (let i = 0; i < N; i++) {
        for (let j = 0; j < N; j++) {
            if (grid[i][j] === word[0]) {
                const visited = Array.from({ length: N }, () => Array(N).fill(false));
                const path = [];
                if (search(i, j, 0, visited, path)) {
                    return path.join(',');
                }
            }
        }
    }
    
    return 'N';
}

// 示例用法
const grid = [
    ['A', 'B', 'C', 'E'],
    ['S', 'F', 'C', 'S'],
    ['A', 'D', 'E', 'E']
];

const word = 'ABCCED';
console.log(findWordInGrid(grid, word)); // 输出: "0,0,0,1,0,2,1,2,2,2,2,1"

代码解释

  1. findWordInGrid:

    • 主函数,接受二维数组 grid 和待查找的字符串 word
    • N 是网格的尺寸。
    • 定义了四个方向:右、左、下、上。
  2. isValid:

    • 检查坐标 (x, y) 是否在网格范围内。
  3. search:

    • 深度优先搜索函数,尝试从 (x, y) 开始匹配 word 中的字符。
    • 使用 visited 数组避免重复使用单元格。
    • 如果匹配成功,将路径添加到 path 中并返回 true
    • 如果匹配失败,回溯(即撤销当前路径并继续搜索)。
  4. for 循环:

    • 遍历二维数组的每个单元格,如果该单元格的字符与 word 的第一个字符匹配,则启动 search 函数。
    • 如果找到了匹配的路径,返回路径坐标的逗号分隔字符串;如果没有找到,返回 'N'

这段代码可以用于在二维字符网格中查找字符串并获取字符位置,如果无法找到字符串则返回 'N'


Pyhton算法源码

def find_word_in_grid(grid, word):
    N = len(grid)
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    
    def is_valid(x, y):
        return 0 <= x < N and 0 <= y < N
    
    def search(x, y, index, visited, path):
        if index == len(word):
            return True
        
        if not is_valid(x, y) or visited[x][y] or grid[x][y] != word[index]:
            return False
        
        visited[x][y] = True
        path.append((x, y))
        
        for dx, dy in directions:
            new_x, new_y = x + dx, y + dy
            if search(new_x, new_y, index + 1, visited, path):
                return True
        
        visited[x][y] = False
        path.pop()
        return False
    
    for i in range(N):
        for j in range(N):
            if grid[i][j] == word[0]:
                visited = [[False] * N for _ in range(N)]
                path = []
                if search(i, j, 0, visited, path):
                    return ','.join(f'{x},{y}' for x, y in path)
    
    return 'N'

# 示例用法
grid = [
    ['A', 'B', 'C', 'E'],
    ['S', 'F', 'C', 'S'],
    ['A', 'D', 'E', 'E']
]

word = 'ABCCED'
print(find_word_in_grid(grid, word))  # 输出: "0,0,0,1,0,2,1,2,2,2,2,1"
  • is_valid: 检查坐标是否在网格内。
  • search: 深度优先搜索,尝试从 (x, y) 开始匹配 word 中的字符。使用 visited 数组来避免重复访问单元格,path 存储当前路径。
  • find_word_in_grid: 遍历网格的每个单元格,如果匹配 word 的第一个字符,调用 search 进行深度优先搜索。返回路径的逗号分隔字符串,如果没有找到,返回 'N'


C算法源码

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define N 3

bool is_valid(int x, int y) {
    return x >= 0 && x < N && y >= 0 && y < N;
}

bool search(char grid[N][N], int x, int y, int index, char *word, bool visited[N][N], int path_x[], int path_y[], int *path_index) {
    if (index == strlen(word)) {
        return true;
    }
    
    if (!is_valid(x, y) || visited[x][y] || grid[x][y] != word[index]) {
        return false;
    }
    
    visited[x][y] = true;
    path_x[*path_index] = x;
    path_y[*path_index] = y;
    (*path_index)++;
    
    int directions[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
    
    for (int i = 0; i < 4; i++) {
        int new_x = x + directions[i][0];
        int new_y = y + directions[i][1];
        if (search(grid, new_x, new_y, index + 1, word, visited, path_x, path_y, path_index)) {
            return true;
        }
    }
    
    visited[x][y] = false;
    (*path_index)--;
    return false;
}

void find_word_in_grid(char grid[N][N], char *word) {
    bool visited[N][N] = { false };
    int path_x[N * N];
    int path_y[N * N];
    int path_index;
    
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (grid[i][j] == word[0]) {
                path_index = 0;
                if (search(grid, i, j, 0, word, visited, path_x, path_y, &path_index)) {
                    for (int k = 0; k < path_index; k++) {
                        printf("%d,%d", path_x[k], path_y[k]);
                        if (k < path_index - 1) {
                            printf(",");
                        }
                    }
                    printf("\n");
                    return;
                }
            }
        }
    }
    
    printf("N\n");
}

int main() {
    char grid[N][N] = {
        {'A', 'B', 'C'},
        {'S', 'F', 'C'},
        {'A', 'D', 'E'}
    };
    
    char word[] = "ABCCED";
    find_word_in_grid(grid, word);  // 输出: "0,0,0,1,0,2,1,2,2,2,2,1"
    
    return 0;
}

  • is_valid: 检查坐标是否在网格内。
  • search: 深度优先搜索,类似于 Python 实现。使用 visited 数组避免重复访问单元格,path_x 和 path_y 存储当前路径的坐标。
  • find_word_in_grid: 遍历网格的每个单元格,调用 search 进行深度优先搜索。输出路径的坐标字符串,如果没有找到,输出 'N'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值