繁体   English   中英

Java递归电话号码字母

[英]Java recursion phone number letters

您如何使用递归方法编写 java 程序,该方法接受一个像“234”这样的整数,并将其转换为手机键盘上的相应字母(2 = ABC,3 = DEF 等),并打印出这个的排列? 例如:

输入 = 234

输出 = ADG ADH ADI AEG AEH AEI AFG AFH AFI BDG BDH BDI BEG BEH BEI BFG BFH BFI CDG CDH CDI CEG CEH CEI CFG CFH CFI


输入 = 89

输出 = TW TX TY TZ UW UX UY UZ VW VX VY VZ

单独生成排列将构成一个很好的家庭作业,更不用说强制递归和电话号码分心了。

通过类似于排序网络的方法,可以有效地生成少量排列。 n 个元素的序列有n! 排列(假设一个完整的 draw ,每个排列也由n 个元素组成)。 观察到,对于二元素序列,有两种排列:

  • 原始序列,和
  • 两个元素交换。

对于三元素序列,有六种排列:

  • 底部两个元素的排列,然后
  • 将序列向右(或向左)旋转一个单元格,以及
  • 底部两个元素的排列,然后
  • 将序列向左(或向右,与上述相反)旋转一个单元格,以及
  • 底部两个元素的排列。

也就是说,它是执行 3 次的双元素版本,中间有两次转换。 现在,一个四元素序列有 24 个排列:

  • 底部三个元素的排列,然后
  • 保存位置1,将0赋给1,将3赋给0,将保存的值赋给3,然后
  • 底部三个元素的排列,然后
  • 交换位置 0 和 2,交换位置 1 和 3(或向右旋转 2),以及
  • 底部三个元素的排列,然后
  • 保存位置3,将2赋值给3,0赋值给2,保存的值赋值为0,然后
  • 底部三个元素的排列。

你开始看到一种模式了吗? 注意到解决方案的递归性质了吗?

以上四个元素,模式更难发现。 您可以向下迭代序列,将所选元素与最后一个元素交换,反转序列,每次扩展底部 24 个排列。

试着把它写在纸上,记录你对元素进行洗牌的步骤,你会发现你已经编写了你需要的程序。


另请注意,此处发布的大多数解决方案都使用String类型并不断将其切碎并重新组装。 String是一个糟糕的选择,因为它是不可变的,当生成排列时,最好通过交换和旋转向量(实际上是ring )中的元素来完成。

您实际上必须将信件写出到目标流是很少见的情况,因此请使您的解决方案偏向于该操作。 使用字符数组并在需要发出特定排列时将字符一个一个地写入流。 形成一个字符串只是为了将条目转储到流中涉及不必要的分配和复制。

  1. 获取输入,转换为字符串

  2. 调用函数 generate(String prefix, String suffix) 前缀为空,转换后的输入为后缀

  3. 在 generate() 中,从后缀中删除第一个数字,将其映射到相应字母的数组,并为数组中的每个字母递归调用 generate(),将其附加到前缀。

import java.util.ArrayList;

class PhoneNumbers
{
    public static void main(String[] args)
    {
        for (String result: convert(args[0]))
            System.out.println(result);
    }

    public static ArrayList<String> convert(String phoneNumber)
    {           
        int digit = Integer.parseInt(phoneNumber.substring(0, 1));
        String letters = new String[] {
            "0",
            "1",
            "ABC",
            "DEF",
            "GHI",
            "JKL",
            // etc...
        }[digit];

        ArrayList<String> result = new ArrayList<String>();

        for (int i = 0; i < letters.length(); ++i) {
            char letter = letters.charAt(i);
            if (phoneNumber.length() > 1) {
                for (String rest: convert(phoneNumber.substring(1)))
                    result.add(letter + rest);
            } else {
                result.add("" + letter);
            }
        }

        return result;
    }
}

java电话号码234

ADG
ADH
ADI
AEG
AEH
AEI
AFG
AFH
AFI
...

这是一个没有数组或数组列表的版本。 结果按照您的要求打印到标准输出。

String[] allLetters = new String[] {
                "0",
                "1",
                "ABC",
                "DEF",
                "GHI",
                "JKL",
                // etc...
        };

public static void convert(String phoneNumber)
{
  convertSubstring(phoneNumber,"");
}

private static void convertSubstring(String phoneNumber, String convertedLetters)
{                   
  int digit = Integer.parseInt(phoneNumber.substring(0, 1));
  String letters=allLetters[digit];
  String remainingString=phoneNumber.substring(1);

  for (int i = 0; i < letters.length(); ++i) 
  {
     char letter = letters.charAt(i);
     String result=convertedLetters+letter;
     if (remainingString.length()==0)
        System.out.println(result);
     else
        convertSubstring(remainingString, result);
  }
}
public class printKeypad {
public static char[] keynotes(int n)
{
    String s[]= {"","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    String s1=s[n-1];
    char c[]=new char[s1.length()];
    for(int i=0;i<c.length;i++)
    {
        c[i]=s1.charAt(i);
    }
    return c;
}
public static void printKeypad(int n)
{
    printKeypad(n,"");
}
public static void printKeypad(int n,String output)
{
    if(n==0)
    {
        System.out.println(output);
        return;
    }
    char c[]=keynotes(n%10);
    for(int i=0;i<c.length;i++)
    {
        printKeypad(n/10,output+c[i]);
    }
}
public static void main(String[] args) {
    int n=23;
    printKeypad(n);
}

} //打印和键盘返回都使用不同的方法来解决

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM