1、生成格雷码
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。
public class GrayCode {
public String[] getGray(int n) {
String[] resStrs = null;
if (n == 1) {
resStrs = new String[] {"0","1"};
} else {
String[] str = getGray(n-1);
resStrs = new String[2*str.length];
for (int i = 0; i < str.length; i++) {
resStrs[i] = "0"+str[i];
resStrs[resStrs.length-1-i] = "1"+str[i];
}
}
return resStrs;
}
}
思路:n位的格雷码都是由n-1位的格雷码生成的,n = 2的格雷码是(00,01,11,10),就是对n = 1的格雷码首位添加0或1,添加0为 0001,添加1需要顺序反向1110,组合起来就是00011110.
2、超长正整数相加
请设计一个算法完成两个超长正整数的加法。
import java.math.BigInteger;
import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String s1 = scanner.nextLine();
String s2 = scanner.nextLine();
BigInteger num1 = new BigInteger(s1);
BigInteger num2 = new BigInteger(s2);
System.out.println(num1.add(num2));
}
}
}
思路:采用BigInteger类解决。
3、火车进站
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有先进站的出站了,后进站的才能出站。要求以字典序排序输出火车出站的序列号。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Main4 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
int[] A = new int[n];
for(int i=0;i<n;i++){
A[i] = in.nextInt();
}
int start = 0;
ArrayList<int[]> result = new ArrayList<int[]>();
Permutation(A,start,n,result);
Set<String> sortResult = new TreeSet<String>();
for(int[] out : result){
if(isLegal(A,out,n)){
StringBuilder sb = new StringBuilder();
for(int i=0;i<n-1;i++){
sb.append(out[i]+" ");
}
sb.append(out[n-1]);
sortResult.add(sb.toString());
}
}
for(String list:sortResult){
System.out.println(list);
}
in.close();
}
}
private static boolean isLegal(int[] in,int[] out,int n){
LinkedList<Integer> stack = new LinkedList<Integer>();
int i=0;
int j=0;
while(i<n){
if(in[i] == out[j]){
i++;
j++;
}else{
if(stack.isEmpty()){
stack.push(in[i]);
i++;
}else{
int top = stack.peek();
if(top ==out[j]){
j++;
stack.pop();
}else if(i<n){
stack.push(in[i]);
i++;
}
}
}
}
while(!stack.isEmpty() && j<n){
int top = stack.pop();
if(top == out[j]){
j++;
}else{
return false;
}
}
return true;
}
private static void Permutation(int[] A,int start,int n,ArrayList<int[]>
result){
if(start == n){
return;
}
if(start == n-1){
int[] B = A.clone();
result.add(B);
return;
}
for(int i=start;i<n;i++){
swap(A,start,i);
Permutation(A,start+1,n,result);
swap(A,start,i);
}
}
private static void swap(int[] A,int i,int j){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}
思路:采用先对火车编号进行排列组合,计算出所有可能的出站情况。但是火车出站的情况需要满足栈的出栈顺序,所以通过火车编号的顺序,排列组合的顺序进行出栈和入栈来比较排列组合中的一组顺序是否满足条件,如果满足,则该排序就是有效的出栈顺序。
4、DNA序列
一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的GC-Ratio可能是基因的起始点。给定一个很长的DNA序列,以及要求的最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。
import java.util.Scanner;
public class Main5 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
int n = scanner.nextInt();
String max = null;
double maxRatio = 0;
for (int i = 0; i < str.length() - n + 1; i++) {
String str2 = str.substring(i, i + n);
if (maxRatio<GiveRatio(str2)) {
max = str2;
maxRatio = GiveRatio(str2);
}
}
System.out.println(max);
}
public static double GiveRatio(String str) {
double ratio=0;
double count=0;
for(char ch : str.toCharArray()){
if(ch=='G' || ch=='C')
count++;
}
ratio = count / (double) str.length();
return ratio;
}
思路:从每个下标开始提取大小为n的字符串计算CG比例,找出最大的子字符串。