字典序问题(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 ...
随机推荐
- js鼠标、键盘事件实例代码
1. 鼠标的哪个按键被点击? <html> <head> <script type="text/javascript"> function wh ...
- python第三章:函数
在前面章节中,介绍了一些input(),print(),len()等内建函数,还有random,math等标准库相关函数,这些都是可以直接使用的,但是很多时候,我们也是可以编写自己的函数. 看个例子: ...
- 18级北航软件学院算法复习--Samshui
A 比特手链 简单模拟 判断 贪心 叶姐要想哥赠送一串比特手链,这个手链由0和1组成.想哥买了手链B,无意间得知叶姐想要同样长度的手链A.想哥囊中羞涩,只能手工调整手链.他希望最少通过以下操作进行最少 ...
- 栈&队列&并查集&哈希表(julyedu网课整理)
date: 2018-11-25 08:31:30 updated: 2018-11-25 08:31:30 栈&队列&并查集&哈希表(julyedu网课整理) 栈和队列 1. ...
- liunx命令的运用
工作中用到了一些命令,记忆才深刻 1.查看服务器内存:free -h 2.查看服务器磁盘空间:df -h 3.切root用户:sudo su root 输入密码 4.查看liunx服务器下的所有用户: ...
- ABP 数据访问 - IRepository 仓储
ABP系列,这个系列来的比较晚,很多大佬其实已经分析过,为什么现在我又来一轮呢? 1.想自己来完整的学习一轮ABP 2.公司目前正在使用ABP,准备迁移Core 基于以上的目的,开始这个系列 ABP ...
- vue自定义指令长按事件
Vue.directive('longpress', { bind: function (el, binding, vNode) { // Make sure expressi ...
- 如何解决 Nginx 端口映射到外网后访问地址端口丢失的问题
1. 问题说明 一个手机h5页面的项目,使用nginx(监听80端口)进行访问,内网访问的地址是192.168.12.125/h5,访问正常,nginx中的配置如下: #微信H5页面访问 locati ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- 不能再被问住了!ReentrantLock 源码、画图一起看一看!
前言 在阅读完 JUC 包下的 AQS 源码之后,其中有很多疑问,最大的疑问就是 state 究竟是什么含义?并且 AQS 主要定义了队列的出入,但是获取资源.释放资源都是交给子类实现的,那子类是怎么 ...