字典序问题(Java)
Description
在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A由 26 个小写英文字母组成A={a,b,…,z}。该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1次。例如,a,b,ab,bc,xyz等字符串都是升序字符串。现在对字母表A 产生的所有长度不超过6 的升序字符串按照字典序排列并编码如下。
对于任意长度不超过6 的升序字符串,迅速计算出它在上述字典中的编码。对于给定的长度不超过6 的升序字符串,计算出它在上述字典中的编码。
Input
输入数据的第一行是一个正整数k,表示接下来共有k行。接下来的k行中,每行给出一个字符串。
Output
将计算结果输出,共有k行,每行对应于一个字符串的编码,对于非法字符串序列输出0。
Sample Input
2
a
b
Sample Output
1
2
import java.io.*;
public class Main {
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static String nextString() throws IOException {
in.nextToken();
return in.sval;
}
public static int nextInt() throws IOException {
in.nextToken();
return (int) in.nval;
}
public static void main(String[] args) throws IOException {
int n = nextInt(); // 读入n行数据
char[] str; // 每行的字符串
int str_num[] = new int[10]; // 字符串长度不超过10
// 按字符串顺序存储每个字符的序列, a存1, b存2
while (n-- > 0) {
int sum = 0; //初始化为0
str = nextString().toCharArray(); // 输入的String转成char
boolean flag = false; // 非法字符串标志为false
// 从字符串第一个字符开始,挨个与后面相邻的作比较,判断是否为非法字符串
for (int i = 0; i < str.length - 1; i++)
if (str[i] >= str[i + 1] || str[i] < 'a' || str[i] > 'z') {
flag = true; //如果不是升序字符串或者有非小写字母的, 非法字符串标记true
break;
}
// 非法字符串输出0
if (flag) {
System.out.println(sum);
continue;
}
// 单个字母a为1, b为2, 后面加的都是除了本身的
// 比如a b c d, d为4, sum = 3(前三个), 还得补上本身的
// 比如ab是27, sum + 前面26个字母 = 26, 所以得先加一个1
sum++;
// 统计每个字母的编码, a = 1, b = 2 ...... z = 26
for (int i = 0; i < str.length; i++)
str_num[i] = str[i] - 'a' + 1;
// 计算小于当前长度的所有字符串情况
// 比如字符串dfgh, 计算字符串长度为1, 2, 3的所有情况
// a-z ab - yz abc - xyz abcd - dfgh
// 组合公式
for (int i = 1; i < str.length; i++)
sum += C(26, i);
// 从初始字母a开始, temp即为1
// 统计abcd - dfgh中间的个数
// abcd - axyz bcde - bxyz cdef - cxyz defg - dfgh
// d efg - d exy d fgh
// dfgh在str_num中存为{4, 6, 7, 8}
int temp = 1;
for (int i = str.length; i > 0; i--) { // 字符串越来越短
//从temp 计算到 str_num, a算到d(不包含d)
for (int j = temp; j < str_num[str.length - i]; j++)
sum += C(26 - j, i - 1);
//dfgh第一次循环计算abcd - axyz bcde - bxyz cdef - cxyz
temp = str_num[str.length - i] + 1; //temp存当前str_num元素 + 1
// dfgh第一次循环temp = 'd' - 'a' + 1 + 1 = 5; 也就是‘e’
// d efg - d exy d fgh
}
out.println(sum);
out.flush();
}
out.close();
}
//计算C(n,m) = n! / (m! * (n-m)!)
public static int C(int n, int m) {
int a, b;
a = 1;
b = 1;
for (int i = n; i > n - m; i--)
a *= i;
for (int i = 1; i <= m; i++)
b *= i;
return a / b;
}
}
字典序问题(Java)的更多相关文章
- Trie树的java实现
leetcode 地址: https://leetcode.com/problems/implement-trie-prefix-tree/description/ 难度:中等 描述:略 解题思路: ...
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- java字典序全排列
import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto&q ...
- HDOJ-ACM1016(JAVA) 字典序全排列,并剪枝
转载声明:原文转自http://www.cnblogs.com/xiezie/p/5576273.html 题意: 一个环是用图中所示的n个圆组成的.把自然数1.2.…….n分别放入每个圆中,并在相邻 ...
- 字典序全排列(java实现)
import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto&q ...
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】
方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...
- java字典序排序
import java.util.Comparator; import java.util.ArrayList; import java.util.Collections; public class ...
- 46. 47. Permutations and Permutations II 都适用(Java,字典序 + 非字典序排列)
解析: 一:非字典序(回溯法) 1)将第一个元素依次与所有元素进行交换: 2)交换后,可看作两部分:第一个元素及其后面的元素: 3)后面的元素又可以看作一个待排列的数组,递归,当剩余的部分只剩一个元素 ...
- 31. Next Permutation (java 字典序生成下一个排列)
题目: Implement next permutation, which rearranges numbers into the lexicographically next greater per ...
随机推荐
- spring boot:用dynamic-datasource-spring-boot-starter配置druid多数据源(spring boot 2.3.3)
一,dynamic-datasource-spring-boot-starter的用途? 1,dynamic-datasource-spring-boot-starter 是一个基于springboo ...
- 运行bee run之后出现的错误以及解决方法Failed to build the application:
运行bee run之后出现的错误以及解决方法 创建一个beego项目 bee new myapp 在该项目执行下面的代码 bee run 出现的问题 2020/04/22 21:12:07 INF ...
- 跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)
前言 对于Redis而言,很多小伙伴只关注其关键的五大基础类型:string.hash.list.set.sorted set(有序集合),其实还有三种特殊类型在很多应用场景也比较适合使用,分别是:b ...
- linux ssh自动输入密码,expect使用
想搞一个使用ssh登录批量ip地址执行命令,自动输入密码的脚本,但是ssh不能使用标准输入来实现自动输入密码,于是了解到了expect这个可以交互的命令 是什么 查看使用man查看expect,是这么 ...
- list.add方法参数详解
- Lock接口示例
Lock 的挂起 await() 唤醒signal() Lock 简单示例 public class LockDemo { public static void main(String[] args ...
- APP UI自动化测试思路总结
python+appium自动化测试系列就要告一段落了,本篇博客咱们做个小结. 首先想要说明一下,APP自动化测试可能很多公司不用,但也是大部分自动化测试工程师.高级测试工程师岗位招聘信息上要求的,所 ...
- git 常用命令大全2
查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show $id gi ...
- 《Head First 设计模式》:迭代器模式
正文 一.定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 要点: 迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象.这样简化了聚合的接口和实现,也让责 ...
- NB-IOT覆盖能力有多强 是怎么实现的
NB-IoT技术中出现以来就以其强大的覆盖能力和通信距离长而受到广大使用者的欢迎,那么NB-IoT覆盖能力究竟是有多大,其覆盖能力应该怎么来衡量? 强大的覆盖能力是NB-IoT技术的最大特点之一,不仅 ...