当前位置: 首页 > 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.jsqmd.com/news/89451/

相关文章:

  • 计算轴向磁铁和环状磁铁的磁场附Matlab代码
  • 从海外硕士到AI产品经理,他的转型之路藏着一个关键选择
  • IDEA 中 maven 图标失踪解决措施
  • 华硕笔记本性能调优新选择:G-Helper实战经验分享
  • 具有飞行约束的无人机MPC模型预测控制研究附Matlab代码
  • (新卷,200分)- 字符串比较(Java JS Python)
  • 静与动的博弈 - 固定与动态Shape下Add算子Tiling实现对比分析
  • 你对电脑上的【Fn】熟悉多少
  • 爱站一键化权重查询v2.0
  • 布隆过滤器
  • 剪映Python自动化:JianYingApi让视频剪辑更智能
  • 等保合规+效率翻倍!首码机房U位资产管理系统的运维升级
  • 【JESD22-B109C】倒装芯片拉伸测试
  • 某PC游戏残血ACE反作弊ring3下的绕过分析
  • 5大信息获取神器深度评测:打破知识壁垒的终极方案
  • 考虑电能交互的冷热电区域多微网系统双层多场景协同优化配置附Matlab代码
  • 考虑阶梯式碳交易与供需灵活双响应的综合能源系统优化调度附Matlab代码
  • Cubmax使用(1)
  • 深入浅出 Android Hook 技术:Frida 框架入门系列
  • 2025年新手入门鱼竿测评:新手鱼竿推荐,新手鱼竿推荐性价比高 - 品牌2026
  • 飞书文档一键导出神器:25分钟搞定700份文档迁移的终极方案
  • 用weditor快速验证你的测试方案原型
  • 考虑可再生能源出力不确定性的商业园区用户需求响应策略附Matlab代码
  • tk私信协议算法
  • 2025年鱼竿前十的品牌推荐,山东威海鱼竿生产厂家值得信赖 - 品牌2026
  • 详细解释pip及其使用方法(对比apt)
  • 深入解析MySQL(7)——SQL调优 - 教程
  • Redis Lua脚本5大实战案例:电商秒杀系统设计
  • 血赚不亏!Java 17 9 个炸裂特性,程序员看完直呼:太香了!
  • conda使用详细指南