Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 计算键盘序列可能的字的有效算法,无需T9_Algorithm - Fatal编程技术网

Algorithm 计算键盘序列可能的字的有效算法,无需T9

Algorithm 计算键盘序列可能的字的有效算法,无需T9,algorithm,Algorithm,免责声明:由于存在一些类似但不相等的问题,请仔细阅读,我只能找到带有T9的键盘的参考资料,但没有人没有 给你一个带字母的手机键盘 2-a、b、c 3-d,e,f 。。。等等 给定一个数字序列,例如222 请求:找出没有T9可以写多少个单词 例如: 222可以是: array (size=4) 0 => string 'C' (length=1) 1 => string 'AB' (length=2) 2 => string 'BA' (length=2)

免责声明:由于存在一些类似但不相等的问题,请仔细阅读,我只能找到带有T9的键盘的参考资料,但没有人没有

  • 给你一个带字母的手机键盘
2-a、b、c

3-d,e,f

。。。等等

  • 给定一个数字序列,例如222
请求:找出没有T9可以写多少个单词

例如:

222可以是:

array (size=4)
  0 => string 'C' (length=1)
  1 => string 'AB' (length=2)
  2 => string 'BA' (length=2)
  3 => string 'AAA' (length=3)
array (size=7)
  0 => string 'AC' (length=2)
  1 => string 'BB' (length=2)
  2 => string 'CA' (length=2)
  3 => string 'AAB' (length=3)
  4 => string 'ABA' (length=3)
  5 => string 'BAA' (length=3)
  6 => string 'AAAA' (length=4)
因此,有4种可能的解决方案

2222可以是:

array (size=4)
  0 => string 'C' (length=1)
  1 => string 'AB' (length=2)
  2 => string 'BA' (length=2)
  3 => string 'AAA' (length=3)
array (size=7)
  0 => string 'AC' (length=2)
  1 => string 'BB' (length=2)
  2 => string 'CA' (length=2)
  3 => string 'AAB' (length=3)
  4 => string 'ABA' (length=3)
  5 => string 'BAA' (length=3)
  6 => string 'AAAA' (length=4)
因此,有7种可能的解决方案

要求:
-无回溯/强力进近
-必须对长序列有效(超过1000位,执行时间少于10秒)
-不需要返回所有可能的单词,只需要返回它们的计数

请注意:我不是在寻找最终的算法,而是关于可能的方法的指示

谢谢

算法/直觉:

import static java.lang.System.out;
public class Solution{    
    public static int possibleStringCount(String s){
        int len = s.length();
        int[] dp = new int[len];
        dp[0] = 1;// possibility is 1 for a single character
        for(int i=1;i<len;++i){
            int possible_chars_length = numberOfRepresentedCharacters(s.charAt(i)-'0') - 1;// because current character itself counts as 1. 
            dp[i] = 0;
            for(int j=i;j>=0;j--){
                if(i - possible_chars_length > j) break;
                if(s.charAt(i) == s.charAt(j)){
                    if(j-1 > -1){
                        dp[i] += dp[j-1];
                    }else{
                        dp[i] += 1;// if there are no combinations before it, then it represents a single character
                    }
                }
            }
        }

        return dp[len-1];
    }

    private static int numberOfRepresentedCharacters(int digit){
       if(digit == 7 || digit == 9) return 4;
        return 3;// it is assumed that digits are between 2-9 always
    }

    public static void main(String[] args) {
        String[] tests = {
            "222","2233","23456789","54667877","5466","7777","22","7898989899","77779999"
        };

        for(String testcase : tests){
            out.println(testcase + " : " + possibleStringCount(testcase));
        }
    }
}
222 : 4
2233 : 4
23456789 : 1
54667877 : 8
5466 : 2
7777 : 8
22 : 2
7898989899 : 26
77779999 : 64
  • 如上图所示,对于单个数字,有3-4种可能性
  • 如果我们按相同的数字2次、3次或4次,屏幕上会显示不同的字符
  • 比如,如果我们按
    2
    • 1次-
      a
    • 2次-
      b
    • 三次-
      c
  • 因此,当我们计算/计算可能的子字符串的数量时,如果发生
    i=i-1=i-2
    的情况,我们需要将
    子问题(i-2)、子问题(i-3)、子问题(i-4)
    值添加到总计数中
  • 例如,让我们以222为例。我们将采取自上而下的办法
  • 222中的第一个2只有一种可能性(即键入
    a
  • 对于222中的第二个2,它可以给我们提供
    a
    ,或者可能是按下
    2
    两次,给我们提供了
    b
    。因此,组合可以是
    aa
    b
  • 对于222中的第三个2,它可以是
    a
    b
    (如果从第二个
    2
    开始)或
    c
  • 因此,每个索引
    i
    的组合数是从
    i
    i-3
    i-4
    的匹配数之和,取决于每个数字在键盘中表示的字符数
  • 请注意,如果第i个字符与
    i-1
    匹配,则我们添加
    dp[i-2]
    而不是
    dp[i-1]
    ,因为
    i-1直到i
    表示单个字符(当多次按下时)
代码:

import static java.lang.System.out;
public class Solution{    
    public static int possibleStringCount(String s){
        int len = s.length();
        int[] dp = new int[len];
        dp[0] = 1;// possibility is 1 for a single character
        for(int i=1;i<len;++i){
            int possible_chars_length = numberOfRepresentedCharacters(s.charAt(i)-'0') - 1;// because current character itself counts as 1. 
            dp[i] = 0;
            for(int j=i;j>=0;j--){
                if(i - possible_chars_length > j) break;
                if(s.charAt(i) == s.charAt(j)){
                    if(j-1 > -1){
                        dp[i] += dp[j-1];
                    }else{
                        dp[i] += 1;// if there are no combinations before it, then it represents a single character
                    }
                }
            }
        }

        return dp[len-1];
    }

    private static int numberOfRepresentedCharacters(int digit){
       if(digit == 7 || digit == 9) return 4;
        return 3;// it is assumed that digits are between 2-9 always
    }

    public static void main(String[] args) {
        String[] tests = {
            "222","2233","23456789","54667877","5466","7777","22","7898989899","77779999"
        };

        for(String testcase : tests){
            out.println(testcase + " : " + possibleStringCount(testcase));
        }
    }
}
222 : 4
2233 : 4
23456789 : 1
54667877 : 8
5466 : 2
7777 : 8
22 : 2
7898989899 : 26
77779999 : 64

我已经写了答案。看看这是否对你有帮助。太棒了!我不明白为什么这个问题被否决,而你的答案没有被否决,但这正是我想要的。如果您在这里添加您的答案,我可以接受/upvote:-)谢谢:)我还没有经过严格的测试,但到目前为止它仍然有效。我要求你在接受之前测试它。是的,我测试了它,我确认它符合我的需要。非常好:-)很高兴提供帮助:-)您可能需要更改变量的数据类型以避免溢出,因为您的长度可以超过1000位。