当前位置: 首页 > news >正文

(新卷,200分)- 字符串拼接(Java JS Python C)

(新卷,200分)- 字符串拼接(Java & JS & Python & C)

题目描述

给定 M(0 < M ≤ 30)个字符(a-z),从中取出任意字符(每个字符只能用一次)拼接成长度为 N(0 < N ≤ 5)的字符串,

要求相同的字符不能相邻,计算出给定的字符列表能拼接出多少种满足条件的字符串,

输入非法或者无法拼接出满足条件的字符串则返回0。

输入描述

给定的字符列表和结果字符串长度,中间使用空格(" ")拼接

输出描述

满足条件的字符串个数

用例
输入abc 1
输出3
说明给定的字符为a,b,c,结果字符串长度为1,可以拼接成a,b,c,共3种
输入dde 2
输出2
说明给定的字符为dde,结果字符串长度为2,可以拼接成de,ed,共2种
题目解析

根据用例2的说明来看,本题是要求解的是:不重复的指定长度的排列。且本题还增加了一个条件,即排列中相邻元素不能相同。

本题的基础是求解排列。

了解的排列的求解后,我们就可以进一步了解不重复的排列求解

而本题只需要在这两题的基础增加:排列中相邻元素不能相同即可。

JS算法源码
const rl = require("readline").createInterface({ input: process.stdin }); var iter = rl[Symbol.asyncIterator](); const readline = async () => (await iter.next()).value; void (async function () { let [s, n] = (await readline()).split(" "); n = parseInt(n); function getResult() { if (s.length < n) { // 无法拼接出满足条件的字符串 return 0; } for (let c of s) { // 输入非法 if (c < "a" || c > "z") return 0; } // 排序cArr,可以方便后面求解全排列时,进行树层去重 const cArr = [...s].sort(); return dfs(cArr, -1, 0, new Array(cArr.length).fill(false), 0); } /** * 全排列求解 * @param {*} cArr 基于cArr数组求解全排列 * @param {*} pre 排列最后一个字符在cArr中的位置 * @param {*} level 排列的长度 * @param {*} used used[i] 用于标记 cArr[i] 元素是否已使用 * @param {*} count 符号要求的排列有几个 * @returns count */ function dfs(cArr, pre, level, used, count) { // 当排列长度到达n,则是一个符合要求的排列 if (level == n) { // 符合要求的排列个数+1 return ++count; } for (let i = 0; i < cArr.length; i++) { // 每个字符只能用一次 if (used[i]) continue; // 相同的字符不能相邻, pre指向前面一个被选择的字符的在cArr中的位置,i指向当前被选择的字符在cArr中的位置 if (pre >= 0 && cArr[i] == cArr[pre]) continue; // 树层去重(去除重复排列) if (i > 0 && cArr[i] == cArr[i - 1] && !used[i - 1]) continue; used[i] = true; count = dfs(cArr, i, level + 1, used, count); used[i] = false; } return count; } console.log(getResult()); })();
Java算法源码
import java.util.Arrays; import java.util.Scanner; public class Main { static String s; static int n; public static void main(String[] args) { Scanner sc = new Scanner(System.in); s = sc.next(); n = sc.nextInt(); System.out.println(getResult()); } public static int getResult() { if (s.length() < n) { // 无法拼接出满足条件的字符串 return 0; } char[] cArr = s.toCharArray(); for (char c : cArr) { // 输入非法 if (c < 'a' || c > 'z') return 0; } // 排序cArr,可以方便后面求解全排列时,进行树层去重 Arrays.sort(cArr); return dfs(cArr, -1, 0, new boolean[cArr.length], 0); } /** * 全排列求解 * * @param cArr 基于cArr数组求解全排列 * @param pre 排列最后一个字符在cArr中的位置 * @param level 排列的长度 * @param used used[i] 用于标记 cArr[i] 元素是否已使用 * @param count 符号要求的排列有几个 * @return count */ public static int dfs(char[] cArr, int pre, int level, boolean[] used, int count) { // 当排列长度到达n,则是一个符合要求的排列 if (level == n) { // 符合要求的排列个数+1 return ++count; } for (int i = 0; i < cArr.length; i++) { // 每个字符只能用一次 if (used[i]) continue; // 相同的字符不能相邻, pre指向前面一个被选择的字符的在cArr中的位置,i指向当前被选择的字符在cArr中的位置 if (pre >= 0 && cArr[i] == cArr[pre]) continue; // 树层去重(去除重复排列) if (i > 0 && cArr[i] == cArr[i - 1] && !used[i - 1]) continue; used[i] = true; count = dfs(cArr, i, level + 1, used, count); used[i] = false; } return count; } }
Python算法源码
# 输入获取 s, n = input().split() n = int(n) # 全排列求解 def dfs(cArr, pre, level, used, count): """ 全排列求解 :param cArr: 基于cArr数组求解全排列 :param pre: 排列最后一个字符在cArr中的位置 :param level: 排列的长度 :param used: used[i] 用于标记 cArr[i] 元素是否已使用 :param count: 符号要求的排列有几个 :return: count """ # 当排列长度到达n,则是一个符合要求的排列 if level == n: # 符合要求的排列个数+1 count += 1 return count for i in range(len(cArr)): # 每个字符只能用一次 if used[i]: continue # 相同的字符不能相邻, pre指向前面一个被选择的字符的在cArr中的位置,i指向当前被选择的字符在cArr中的位置 if pre >= 0 and cArr[i] == cArr[pre]: continue # 树层去重(去除重复排列) if i > 0 and cArr[i] == cArr[i - 1] and not used[i - 1]: continue used[i] = True count = dfs(cArr, i, level + 1, used, count) used[i] = False return count # 算法入口 def getResult(): if len(s) < n: # 无法拼接出满足条件的字符串 return 0 for c in s: if c < 'a' or c > 'z': # 输入非法 return 0 cArr = list(s) # 排序cArr,可以方便后面求解全排列时,进行树层去重 cArr.sort() return dfs(cArr, -1, 0, [False] * len(cArr), 0) # 算法调用 print(getResult())
C算法源码
#include <stdio.h> #include <stdlib.h> #define MAX_SIZE 31 char s[MAX_SIZE]; int s_len; int n; /*! * 全排列求解 * @param pre 排列最后一个字符在cArr中的位置 * @param level 排列的长度 * @param used used[i] 用于标记 s[i] 元素是否已使用 * @param count 符号要求的排列有几个 * @return count */ int dfs(int pre, int level, int used[], int count) { // 当排列长度到达n,则是一个符合要求的排列 if (level == n) { // 符合要求的排列个数+1 return ++count; } for (int i = 0; i < s_len; i++) { // 每个字符只能用一次 if (used[i]) continue; // 相同的字符不能相邻, pre指向前面一个被选择的字符的在s中的位置,i指向当前被选择的字符在s中的位置 if (pre >= 0 && s[i] == s[pre]) continue; // 树层去重(去除重复排列) if (i > 0 && s[i] == s[i - 1] && !used[i - 1]) continue; used[i] = 1; count = dfs(i, level + 1, used, count); used[i] = 0; } return count; } int cmp(const void *a, const void *b) { return *((char *) a) - *((char *) b); } int getResult() { int i = 0; while (s[i] != '\0') { // 输入非法 if (s[i] < 'a' || s[i] > 'z') return 0; i++; } s_len = i; if (s_len < n) { // 无法拼接出满足条件的字符串 return 0; } // 排序s,可以方便后面求解全排列时,进行树层去重 qsort(s, i, sizeof(char), cmp); int used[MAX_SIZE] = {0}; return dfs(-1, 0, used, 0); } int main() { scanf("%s", s); scanf("%d", &n); printf("%d\n", getResult()); return 0; }
http://www.cnnetsun.cn/news/53560.html

相关文章:

  • OpenHarmony AI人脸识别与手势控制系统开发指南
  • 新一代空间感知驱动的军工仓库与硐室透明化管控技术研究
  • Sketch MeaXure插件:设计师必备的智能标注工具
  • 强化学习Q-learning求最优策略
  • 你对电脑上的【Fn】熟悉多少
  • 计及N-k安全约束的含光热电站电力系统优化调度模型【IEEE14节点、118节点】附Matlab代码
  • 计及需求响应的粒子群算法求解风能、光伏、柴油机、储能容量优化配置附Matlab代码
  • conda使用详细指南
  • 豆包与DeepSeek底层大模型的深度解析:技术架构、设计理念与生态分野
  • Linux系统中的socket激活:先创建监听端口,后启动程序
  • 从零解决pyproject.toml构建失败的实战指南
  • Redis Lua脚本入门:从零写出你的第一个原子操作
  • 旧机转手不再慌!电子产品信息清除新国标落地,核心技术逻辑全解析
  • 安全体验馆好用供应商
  • 第二章——数据分析场景之Python数据可视化:用Matplotlib与Seaborn绘制洞察之图
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生离校管理系统小程序设计与实现(丰富项目+远程调试+讲解+定制)
  • 如何用AI工具jstat优化Java应用性能分析
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生信息管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • Day 38 GPU训练及类的call方法
  • 【Python实战】火爆全网的“隔空手势画板”是如何实现的?教你用OpenCV+MediaPipe复刻钢铁侠黑科技!
  • 【学习笔记】如果打造可复现、可评测、可迭代的AI技术体系
  • 【论文自动阅读】See Once, Then Act: Vision-Language-Action Model with Task Learning from One-Shot Video Demo
  • 利用齐次坐标系证明各种几何定理【射影几何】
  • 小程序基于springboot的乡镇普法知识科普宣传系统 律师预约系统设计与实现_qf4cwws6(java毕业设计项目源码)
  • 面向对象编程三大特性:封装、继承、多态的核心要义
  • leetcode 2147. 分隔长廊的方案数 困难
  • 学生党必备!这款桌面课表工具太省心了
  • 深度学习实验14代码
  • 优化及性能-–-behaviac
  • 练题100天——DAY26:汇总区间+丢失的数字+数组交集