字典序问题(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:使用分布式事务seata(druid 1.1.23 / seata 1.3.0 / mybatis / spring boot 2.3.2)
一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件开源的分布式事务解决方案. 前身是阿里的F ...
- django环境安装与项目创建方式
1.安装django pip install django2.检查django版本 : python -m django --version 3.创建项目 django-admin startproj ...
- 一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...
- volatile与重排序
使用关键字volatile可以禁止代码的重排序: 在Java程序运行时,JIT(即使编译器)可以动态地改变程序代码运行地顺序:例如,有如下代码: A代码-重耗时 B代码-轻耗时 C代码-重耗时 D代码 ...
- Java 等待/通知机制
等待/通知的目的是确保等待线程从wait()方法返回时能够感知到通知线程对变量所做出的的修改: 等待方遵循如下原则: 1.获取对象的锁 2.如果条件不满足,那么调用对象的wait()方法,被通知后任要 ...
- js堆排序
堆的预备知识 堆是一个完全二叉树. 完全二叉树: 二叉树除开最后一层,其他层结点数都达到最大,最后一层的所有结点都集中在左边(左边结点排列满的情况下,右边才能缺失结点). 大顶堆:根结点为最大值,每个 ...
- Windows搭建Hexo系统
date: 2018-11-16 17:10:51 updated: 2018-11-16 20:04:43 1.安装Git 下载Windows下的Git客户端并安装,安装很简单,基本一路Next下去 ...
- java数据结构-11循环双端队列
@SuppressWarnings("unchecked") public class CircleDeque<E> { private int front; priv ...
- Redis---01简述目录结构与redis.conf文件
一.Redis目录结构 (当前Redis是在CentOS 7 1708 64位环境下,Redis版本为3.2.5) 进入默认的Redis安装目录/usr/local/bin,可以看见这些下图目录结构 ...
- 02 HTML 常见标记 选择器 样式
no.02今天主要学习了在web中的HTML CSS,并在其中制作了明信片,在制作明信片途中有几个知识点需要总结:1.HTML 全称hyper text markup language 超文本标记语言 ...