锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Rosalind Java|Enumerating k-mers Lexicographically

时间:2022-11-28 18:00:01 mers00002型细胞电阻仪

Rosalind编程问题排列组合字母K-mers。

Enumerating k-mers Lexicographically

Problem:
Assume that an alphabet A has a predetermined order; that is, we write the alphabet as a permutation A=(a1,a2,…,ak), where a1

Given two strings s and t having the same length n, we say that s precedes t in the lexicographic order (and write s

Given: A collection of at most 10 symbols defining an ordered alphabet, and a positive integer n (n≤10).
Sample input

A C G T
2

Return: All strings of length n that can be formed from the alphabet, ordered lexicographically (use the standard order of symbols in the English alphabet).
Sample output

AA
AC
AG
AT
CA
CC
CG
CT
GA
GC
GG
GT
TA
TC
TG
TT


简单总结一下题目大意:给出一系列英文字母和数字n,所有需要输出n字母的组合。
看似很简单的题目,但背后需要深入学习java语法很详细。

先分析解题思路:
1.读取所有英文字母(手动去除间隔空间)和k-mers长度n。
2.第一个循环读取所有英文字母到集合。
3.将所有英文字母逐一添加到原始元素到原始元素尾缀中。
4.判断长度不为n的元素并删除。
5.增强for循环输出结果到屏幕。

以下是实现代码:

public class Enumerating_kmers_Lexicographically { 
             public static void main(String[] args) { 
                 //1.输入组合长度n和待组合字母         Scanner sc = new Scanner(System.in);         System.out.println("请输入组合长度n:");         int n = sc.nextInt();          Scanner sr = new Scanner(System.in);         System.out.println("请输入待组合的字母:");//网站给出的文件有空间间隔,这里输入需要去除空间。         String alphabet = sr.nextLine();      //2.添加元素并最终输出         List<String> finalalphabet = new ArrayList<>();
        kmers(alphabet, finalalphabet, n, 0);

    }

    public static void kmers(String alphabet, List<String> finalalphabet, int n, int i) { 
        //初始默认i为0,意为从第一个字母开始遍历产生kmers
        while (i < n) { 
        
            i += 1;
            //从第二轮循环开始向原有元素累加新字符
            if (i != 1) { 
        
                int size = finalalphabet.size();
                for (int k = 0; k < size; k++) { 
        
                    for (int j = 0; j < alphabet.length(); j++) { 
        
                        finalalphabet.add(finalalphabet.get(k) + alphabet.charAt(j));
                    }
                }

                //使用列表迭代器循环删除元素
                ListIterator<String> lit = finalalphabet.listIterator();
                while (lit.hasNext()) { 
        
                    String s = lit.next();
                    if (s.length() < i) { 
        
                        lit.remove();//迭代器删除,可以防止删除改变ArrayList大小改变导致的并发修改异常。
                    }
                }


            } else { 
        //第一轮循环直接添加元素进数组
                for (int j = 0; j < alphabet.length(); j++) { 
        
                    finalalphabet.add(String.valueOf(alphabet.charAt(j)));
                }
            }

        }
        for (String s : finalalphabet) { 
        
            System.out.println(s);
        }
    }
}

迭代器并发修改错误

撰写上述代码时,“使用列表迭代器循环删除元素”一步至关重要,可以方便后继遍历添加元素,同时及时清理内存。但是小编在写这一部分的时候会提示报错,原有的代码为:

for (String s : finalalphabet) { 
        
     if (s.length()<i){ 
        
        finalalphabet.remove(s) ;
     }
}

原因是当finalalphabet删除元素s之后,导致finalalphabet自身大小发生改变,for循环遍历就会产生ConcurrentModificationException并发修改异常。 不过Java非常贴心地准备了迭代器工具,通过迭代器遍历即可实现在不报错的情况下删除目标元素。具体方法参上。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章