当前位置: 首页 > 科技观察

使用Java8函数式编程生成字母序列_0

时间:2023-03-13 09:21:59 科技观察

使用Java8中的函数式编程生成字母序列是一个相当大的挑战。LukasEder愉快地接受了挑战,他将向我们展示如何使用Java8生成ABC序列——当然,当然不会以糟糕的方式。StackOverflow上的“mip”伙伴提出的一个有趣问题让我很困惑。问题是:123我正在寻找生成以下字母序列的方法:A、B、C、...、Z、AA、AB、AC、...、ZZ。您应该很快就能认出它下面是Excel电子表格的标题,它看起来就是这样:到目前为止,还没有一个答案是使用Java8中的函数式编程实现的,所以我接受挑战。我将使用jOOλ,因为Java8的StreamAPI没有为此任务提供足够的功能(我承认我错了——非常感谢Sebastian对这个问题的有趣回答)。首先,我们以函数式的方式分解算法。我们需要的组件是:1.一个(可重复的)字母表。2.一个上限,比如你想生成多少个字母。如果需要生成序列ZZ,则上界为2。3、将字母表中的字母与之前生成的字母组合成笛卡尔积的方法。我们看一下代码:1.生成字母表我们可以这样写字母表:1Listalphabet=Arrays.asList("A","B",...,"Z");但这很糟糕。我们改用jOOλ:1234Listalphabet=Seq.rangeClosed('A','Z').map(Object::toString).toList();关闭区间(Java-8-Stream-speak包括上边界),然后将字符映射成字符串,最后转成列表。到目前为止,一切都很好。现在:2.使用上边界:需要的字符序列包括:1A..Z,AA,AB,..ZZ但是我们应该很容易想到扩展这个需求,可以生成如下字符序列,或者更多:1个。.Z,AA,AB,..ZZ,AAA,AAB,..ZZZ所以我们将再次使用rangeClosed():1234//1=A..Z,2=AA..ZZ,3=AAA。.ZZZSeq.rangeClosed(1,2).flatMap(length->...).forEach(System.out::println);该方法为[1..2]范围内的每个长度生成一个单独的流,然后将这些流组合成单个流。flatMap()的本质类似于命令式编程中的嵌套循环。3.将字母合并成笛卡尔积这是最棘手的部分:我们需要合并字符及其出现次数。因此,我们将使用这样的流:12345Seq.rangeClosed(1,length-1).foldLeft(Seq.seq(alphabet),(s,i)->s.crossJoin(Seq.seq(字母表)).map(t->t.v1+t.v2)));我们再次使用rangeClosed()来生成[1..length-1]范围内的值。foldLeft()与reduce()基本相同,区别在于foldLeft()保证流中的顺序是“从左到右”,不需要fold函数关联。另一方面,它是一个易于理解的词汇:foldLeft()简单地表示一个循环命令。循环的“起点”(即循环的初始值)是一个完整的字母表(Seq.seq(alphabet))。现在,[1..length-1]范围内的值生成一个笛卡尔积(crossJoin()),产生一个新的字母表,然后我们将每个合并的字母组合成一个字符串(t.v1和t.v2).这就是整个过程。把上面的放在一起这是一个简单的程序,它打印A..Z,AA..ZZ,AAA..ZZZ到控制台:1234567891011121314151617importorg.jooq。lambda.Seq;公共类测试{publicstaticvoidmain(String[]args){intmax=3;Listalphabet=Seq.rangeClosed('A','Z').map(Object::toString).toList();Seq.rangeClosed(1,max).flatMap(length->Seq.rangeClosed(1,length-1).foldLeft(Seq.seq(alphabet),(s,i)->s.crossJoin(Seq.seq(alphabet)).map(t->t.v1+t.v2))).forEach(System.out::println);}}免责声明对于这个问题,这确实不是最好的算法。在StackOverflow上,一位匿名用户给出了黑客的实现方法。12345678910导入静态java.lang.Math.*;privatestaticStringgetString(intn){char[]buf=newchar[(int)floor(log(25*(n+1))/log(26))];for(inti=buf.length-1;i>=0;i--){n--;buf[i]=(char)('A'+n%26);n/=26;}返回新字符串(buf);不用说,这个算法会比之前的函数式算法快很多。原文链接:jaxenter翻译:ImportNew.com-paddx翻译链接:http://www.importnew.com/16727.html