2024-08-15

题目:矩阵匹配

给定两个矩阵A和B,它们的大小都是 N * M,现在要求你找出 A 矩阵中的所有包含 B 矩阵的子矩阵,并输出这些子矩阵的左上角的位置和右下角的位置。

示例:

输入:

A = [

[1,2,3,4],

[4,5,6,5],

[7,8,9,10],

[11,12,13,14]

]

B = [

[4,5,6],

[10,11,12]

]

输出:

[

{

"left-top": [1, 1],

"right-bottom": [2, 3]

},

{

"left-top": [2, 0],

"right-bottom": [3, 2]

}

]

解释:

在 A 矩阵中,有两个地方包含 B 矩阵:

  1. 左上角为 [1,1],右下角为 [2,3]
  2. 左上角为 [2,0],右下角为 [3,2]

注意:

  1. 矩阵以行和列的索引表示,索引从0开始。
  2. 矩阵A的行数大于等于B的行数,列数大于等于B的列数。
  3. 矩阵B的行和列都是不同的。
  4. 输出的结果需要按照左上角的行索引升序排列,行索引相同则按列索引升序排列。

提示:

  • 时间复杂度应该是 O(NMT),其中 T 是 B 矩阵的面积。
  • 空间复杂度应该是 O(T)。

解法:




public class Solution {
    public int[][] findSubmatrix(int[][] A, int[][] B) {
        // 实现代码
    }
}

请你在下面提供实现这个算法的代码。在提交答案时,请确保你的代码是正确的,并且足够高效。

2024-08-15

在JavaScript中调用API接口通常使用XMLHttpRequestfetch API。以下是使用fetch的示例代码:




// 定义API的URL
const apiUrl = 'https://api.example.com/data';
 
// 使用fetch调用API接口
fetch(apiUrl)
  .then(response => {
    if (response.ok) {
      return response.json(); // 将响应数据转换为JSON
    }
    throw new Error('Network response was not ok.');
  })
  .then(data => {
    console.log('API Response:', data); // 处理API返回的数据
  })
  .catch(error => {
    console.error('Error fetching API:', error); // 处理错误
  });

确保API的URL是正确的,并且服务器端配置了CORS以允许跨域请求(如果需要)。如果API需要认证,你可能需要在请求中包含认证信息,如API密钥或令牌。

2024-08-15

这是一个针对华为OD机试题目的简化版描述,原题可能涉及到复杂的输入输出格式和边界条件处理,以下是一个简化版的代码实例,用于演示如何识别字符串中的重复部分。




// Java 版本
public class Main {
    public static void main(String[] args) {
        String input = "abcabcabc";
        String repeatedStr = findRepeated(input);
        System.out.println(repeatedStr); // 输出 "abc"
    }
 
    private static String findRepeated(String input) {
        for (int i = 1; i <= input.length() / 2; i++) {
            if (input.length() % i == 0 && input.repeat(i).contains(input)) {
                return input.substring(0, i);
            }
        }
        return "";
    }
}



// JavaScript 版本
function findRepeated(input) {
    for (let i = 1; i <= input.length / 2; i++) {
        if (input.length % i === 0 && input.repeat(i).includes(input)) {
            return input.substring(0, i);
        }
    }
    return '';
}
 
console.log(findRepeated("abcabcabc")); // 输出: abc



# Python 版本
def find_repeated(input_str):
    for i in range(1, len(input_str) // 2 + 1):
        if len(input_str) % i == 0 and input_str * (len(input_str) // i) in input_str:
            return input_str[:i]
    return ''
 
print(find_repeated("abcabcabc"))  # 输出: abc



// C++ 版本
#include <iostream>
#include <string>
using namespace std;
 
string findRepeated(string input) {
    for (int i = 1; i <= input.length() / 2; i++) {
        if (input.length() % i == 0 && input.substr(0, i) == input.substr(i, i)) {
            return input.substr(0, i);
        }
    }
    return "";
}
 
int main() {
    string input = "abcabcabc";
    cout << findRepeated(input) << endl; // 输出 "abc"
    return 0;
}

以上代码示例都是基于字符串中存在重复部分,且重复部分是连续的情况。如果重复部分不一定连续,或者是其他类型的重复(如数字序列中的重复模式),则需要调整算法来适应不同的需求。

2024-08-15

在Java后端使用Bouncy Castle库实现SM2加密,并在Vue前端进行调用和展示。

后端Java代码示例:




import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.modes.GMTEncryptingState;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
 
import java.security.KeyFactory;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
 
public class SM2Encryption {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
 
    public static String generateKeyPair() {
        ECKeyPairGenerator keyGenerator = new ECKeyPairGenerator();
        keyGenerator.init(new ECKeyPairGenerator.ECKeyGenerationParameters(
                ECDomainParameters.sm2p256v1,
                new SecureRandom()
        ));
 
        AsymmetricCipherKeyPair keyPair = keyGenerator.generateKeyPair();
        ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();
        ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
 
        // 私钥
        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
        java.security.PrivateKey privateKeyJava = keyFactory.generatePrivate(privateKeySpec);
 
        // 公钥
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKey.getQ().getEncoded(false));
        java.security.PublicKey publicKeyJava = keyFactory.generatePublic(publicKeySpec);
 
        // 将私钥和公钥转换为Base64以便传输
        String privateKeyStr = Base64.getEncoder().encodeToString(privateKeyJava.getEncoded());
        String publicKeyStr = Base64.getEncoder().encodeToStr
2024-08-15

由于篇幅所限,我无法提供完整的Vue和Java版本的2048游戏实现。但我可以提供一个简化的游戏逻辑实现,并指出关键的步骤。

Vue版本的2048游戏:




<template>
  <div id="app">
    <div v-for="(row, rowIndex) in grid" :key="rowIndex">
      <div v-for="(value, colIndex) in row" :key="colIndex">
        <div :class="'tile tile-' + value" @click="move(rowIndex, colIndex)">
          {{ value }}
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  name: 'App',
  data() {
    return {
      grid: [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
      ],
      score: 0
    };
  },
  methods: {
    move(row, col) {
      // 实现移动逻辑
    },
    addRandomTile() {
      // 添加随机数字块逻辑
    }
  },
  mounted() {
    this.addRandomTile();
    this.addRandomTile();
  }
};
</script>

Java版本的2048游戏:




public class Game2048 {
    private int[][] grid = new int[4][4];
    private Random random = new Random();
 
    public void addRandomTile() {
        int value = random.nextInt(10) == 0 ? 4 : 2;
        int row = random.nextInt(4);
        int col = random.nextInt(4);
        while (grid[row][col] != 0) {
            row = (row + 1) % 4;
            col = (col + 1) % 4;
        }
        grid[row][col] = value;
    }
 
    public void move(int direction) {
        // 实现移动逻辑
    }
 
    public static void main(String[] args) {
        Game2048 game = new Game2048();
        game.addRandomTile();
        game.addRandomTile();
        // 控制台输出当前grid状态
        for (int[] row : game.grid) {
            System.out.println(Arrays.toString(row));
        }
    }
}

在Vue和Java版本的实现中,移动和随机数字块添加的逻辑需要进一步详细实现。这些是游戏的核心部分,涉及到游戏的规则和算法。对于完整的实现,你需要处理用户的移动指令,合并相同的数字块,检测游戏是否结束,记录分数等功能。

2024-08-15

学习Vue.js的基础知识和如何使用Vue CLI创建项目,并且使用Element UI组件库来快速搭建前端界面。

  1. 安装Vue CLI:



npm install -g @vue/cli
# 或者
yarn global add @vue/cli
  1. 创建一个新的Vue项目:



vue create my-project
  1. 进入项目目录并启动项目:



cd my-project
npm run serve
# 或者
yarn serve
  1. 安装Element UI:



npm install element-ui --save
# 或者
yarn add element-ui
  1. 在Vue项目中引入Element UI:



// main.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'
 
Vue.use(ElementUI)
 
new Vue({
  el: '#app',
  render: h => h(App)
})
  1. 使用Element UI组件:



<template>
  <div>
    <el-button type="primary">点击我</el-button>
  </div>
</template>
 
<script>
export default {
  // 组件逻辑
}
</script>
 
<style>
/* 组件样式 */
</style>

以上步骤为学习者提供了从零开始搭建Vue项目和使用Element UI的基础,之后可以根据具体需求进行深入学习和研究。

2024-08-14

在Java中,流式处理通常是通过java.util.stream包中的Streams API来实现的。以下是一个简单的例子,展示了如何使用Java Streams API来处理一个集合:




import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class StreamExample {
    public static void main(String[] args) {
        // 创建一个列表
        List<String> items = Arrays.asList("apple", "banana", "orange", "kiwi");
 
        // 使用流来过滤出长度大于5的字符串
        List<String> filteredItems = items.stream()
                                          .filter(s -> s.length() > 5)
                                          .collect(Collectors.toList());
 
        // 打印过滤后的结果
        filteredItems.forEach(System.out::println);
    }
}

这段代码首先创建了一个包含几个字符串的列表。然后,使用stream()方法将列表转换成流,接着使用filter()方法来过滤出长度大于5的字符串。最后,使用collect()方法将过滤后的流收集成一个新的列表。

这只是流式处理的一个非常基本的例子。Java Streams API 提供了许多其他的操作,如map()sorted()reduce()等,可以用来进行更复杂的数据处理。

2024-08-14



import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
 
public class ExcelExportExample {
 
    public static void main(String[] args) throws IOException {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("ExampleSheet");
 
        // 创建表头
        Row header = sheet.createRow(0);
        header.createCell(0).setCellValue("序号");
        header.createCell(1).setCellValue("姓名");
        header.createCell(2).setCellValue("生日");
 
        // 填充数据
        for (int rowNum = 1; rowNum < 10; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 3; cellNum++) {
                Cell cell = row.createCell(cellNum);
                switch (cellNum) {
                    case 0:
                        cell.setCellValue(rowNum);
                        break;
                    case 1:
                        cell.setCellValue("姓名" + rowNum);
                        break;
                    case 2:
                        cell.setCellValue(setDateCellStyle(row.createCell(cellNum), getRandomDate()));
                        break;
                }
            }
        }
 
        // 写入到文件
        try (FileOutputStream outputStream = new FileOutputStream("example.xlsx")) {
            workbook.write(outputStream);
        }
        workbook.close();
    }
 
    private static Date getRandomDate() {
        // 这里生成一个随机日期,仅用作示例
        long randomDateMillis = System.currentTimeMillis() - (long) (Math.random() * 10000);
        return new Date(randomDateMillis);
    }
 
    private static CellStyle setDateCellStyle(Cell cell, Date date) {
        CreationHelper createHelper = cell.getSheet().getWorkbook().getCreationHelper();
        CellStyle cellStyle = cell.getSheet().getWorkbook().createCellStyle();
        cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd"));
        cell.setCellStyle(cellStyle);
        cell.setCellValue(date);
        return cellStyle;
    }
}

这段代码使用Apache POI库创建了一个Excel文件,并填充了数据和样式。其中,setDateCellStyle方法设置了日期的样式,并处理了时间转换问题。这是一个简化的例子,展示了如何使用Apache POI处理Excel导出的基本方法。

2024-08-14



// 抽象化角色:图形接口
interface Shape {
    void draw();
}
 
// 实现化角色:具体图形类
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle is drawn.");
    }
}
 
class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle is drawn.");
    }
}
 
// 抽象化角色:颜色接口
interface Color {
    void fill();
}
 
// 实现化角色:具体颜色类
class Red implements Color {
    @Override
    public void fill() {
        System.out.println("Color is red.");
    }
}
 
class Green implements Color {
    @Override
    public void fill() {
        System.out.println("Color is green.");
    }
}
 
// 桥接角色:桥接类
class Bridge {
    private Shape shape;
    private Color color;
 
    public Bridge(Shape shape, Color color) {
        this.shape = shape;
        this.color = color;
    }
 
    public void draw() {
        shape.draw();
        color.fill();
    }
}
 
// 客户端代码
public class BridgePatternDemo {
    public static void main(String[] args) {
        // 创建一个红色的圆
        Bridge bridge = new Bridge(new Circle(), new Red());
        bridge.draw();  // 输出: Circle is drawn. Color is red.
    }
}

这个代码示例展示了如何使用桥接模式来将图形的绘制和颜色填充进行分离,从而可以独立地对它们进行扩展。在客户端代码中,我们创建了一个红色的圆形,并调用了draw()方法,它会分别调用图形的draw()和颜色的fill()方法,输出相应的信息。这样的设计使得每个类都可以独立地扩展和改变,满足开闭原则。