给定数字字符串,返回字母组合

博客围绕给定仅含数字 2 - 9 的字符串,求解其能表示的所有字母组合展开。给出数字到字母的映射规则,以输入“23”为例展示输出结果。分析了用 switch case 语句表示数字与字母对应关系,以及添加字母的处理方式,还提及代码实现和运行结果。

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

例:输入“23”
输出 :[ ad, bd, cd, ad, ae, af, bd, be, bf, cd, ce, cf]
分析:
首先用switch case语句将数字和该数字对应 的字母表示出来。
然后再给定一个字符串。每次向里面添加一个字母,把之前添加过的做为一个整体,新的的第一组覆盖之前的,因为有重复。
代码实现:


import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class pipeiSolution {
    public static String mapping(char n){  //数字到字母的对应
        String str=null;
        switch(n){
            case '0':
                str="";
                break;
            case'1':
                str="";
                break;
            case'2':
                str="abc";
                break;
            case'3':
                str="def";
                break;
            case'4':
                str="ghi";
                break;
            case'5':
                str="jkl";
                break;
            case'6':
                str="mno";
                break;
            case'7':
                str="pqrs";
                break;
            case'8':
                str="tuv";
                break;
            case'9':
                str="wxyz";
                break;
        }
        return str;
    }
    public static  List<String> letterCombinations(String datas){
        List<String> ret=new ArrayList<>();
        int i=0;
        for(i = 0;i<datas.length();i++){
            char c=datas.charAt(i);
            int length=ret.size();
            String substring=mapping(c);
            if(length==0){
                for(int j=0;j<substring.length();j++){
                    ret.add(" "+substring.charAt(j));    //直接加
                }
            }
            else{
                for(int p=0;p<length;p++){
                    for(int m=0;m<substring.length();m++){
                        ret.add(ret.get(p)+substring.charAt(m));  //加入除第一组的其他组合
                    }
                    ret.set(p,(ret.get(p)+substring.charAt(0)));  //覆盖之前的
                }
            }
        }
        return ret;
    }

    public static void main(String[] args) {
    Scanner scan=new Scanner(System.in);
        System.out.println("please input the string: ");
        String datas=scan.nextLine();
        System.out.println(letterCombinations(datas));

    }
}


运行结果:
在这里插入图片描述

<think>题目要求:从一个混合了数字字符串数字和其他字符的列表中提取纯数字字符串,并将它们拼接成一个大字符串。 分析: 1. 输入是一个列表,其中元素可能是字符串(可能是纯数字字符串,也可能是包含非数字字符的字符串),也可能是整数或浮点数。 2. 我们需要提取的是“纯数字字符串”,注意要求是字符串形式,并且整个字符串完全由数字组成(例如"123")。注意,数字本身(如整数123)不是字符串,所以不在提取范围。 3. 另外,题目中可能还包含其他类型的字符串,比如"hello"、"a123"(这种不是纯数字字符串)等,这些都不需要提取。 4. 提取后的纯数字字符串,需要将它们拼接成一个大的字符串。 步骤: 1. 遍历列表中的每个元素。 2. 判断元素是否为字符串类型,并且该字符串是否只包含数字字符(即0-9)。 3. 如果是,则保留这个字符串。 4. 将筛选出的所有纯数字字符串拼接起来。 注意:题目要求的是纯数字字符串,所以对于非字符串类型(如整数、浮点数)我们不提取。但是,如果题目要求将整数和浮点数也转换为字符串并提取,那么需要另外处理。但根据问题描述,我们只提取纯数字字符串。 然而,引用[4]中有一个例子,从字符串中提取数字,但那是从单个字符串中提取数字字符,而我们的问题是从列表中提取纯数字字符串。 另外,引用[3]中提到了使用正则表达式提取字符串中的数字,但我们的问题不是从字符串中提取数字,而是直接判断整个字符串是否为纯数字。 因此,我们可以这样实现: 方法1:使用字符串的isdigit方法 - 首先,筛选出所有字符串类型的元素。 - 然后,在这些字符串中,使用isdigit()方法判断是否整个字符串都是数字。 注意:isdigit()方法对于非负整数的字符串有效,如果字符串包含负号或小数点,则isdigit()返回False。但题目要求是纯数字字符串,通常指的是正整数形式的字符串。如果题目要求包括负数或浮点数,那么需要另外处理,但根据问题描述,我们只提取纯数字字符串(即正整数形式的字符串)。 方法2:使用正则表达式匹配 - 我们可以用正则表达式来匹配整个字符串是否由数字组成,即^[0-9]+$。 但是,由于问题要求的是整个字符串都是数字,所以使用isdigit()更简单。 步骤代码: result = [] # 用于存放符合条件的纯数字字符串 for item in mixed_list: if isinstance(item, str) and item.isdigit(): result.append(item) # 然后拼接 big_string = ''.join(result) 但是,这里有一个注意点:如果列表中有整数或浮点数,我们并不提取,因为题目要求的是纯数字字符串。所以整数和浮点数即使可以转换为数字,但它们不是字符串形式,所以不提取。 但是,如果问题要求将整数和浮点数也当作数字字符串提取出来,那么我们需要先将整数和浮点数转换为字符串,然后再判断?但题目要求是“纯数字字符串”,所以整数和浮点数本身不是字符串,所以不在提取范围内。 因此,我们只处理字符串类型的元素。 示例: 输入:mixed_list = [123, "123", "45a", "67", "89.1", "hello", "000", "12"] 输出:大字符串为 "1236700012" 解释: 123 -> 整数,跳过。 "123" -> 字符串且全是数字,保留。 "45a" -> 包含非数字字符,跳过。 "67" -> 保留。 "89.1" -> 包含小数点,跳过(因为isdigit()为False)。 "hello" -> 非数字,跳过。 "000" -> 是纯数字字符串,保留。 "12" -> 保留。 拼接后:'123'+'67'+'000'+'12' = "1236700012" 但是,注意题目要求是“纯数字字符串”,所以上述处理符合要求。 另外,如果列表中有负数字符串,例如["-123"],由于isdigit()对于负号返回False,所以也会被跳过。同样,浮点数字符串如"3.14"也会被跳过。 如果题目要求包括负数和浮点数,那么我们需要重新定义“纯数字字符串”,但根据问题描述,我们只处理正整数形式的字符串。 因此,代码如下:</think>### 解决Python混合列表提取纯数字字符串问题 #### 问题分析 需要从一个混合了数字字符串数字和其他字符的列表中: 1. 提取**纯数字字符串**(如"123") 2. 过滤非数字字符串(如"abc")和数字类型(如整数123) 3. 将提取的纯数字字符串拼接为一个大字符串 #### 解决方案 ##### 方法1:使用`isdigit()`方法(推荐) ```python def extract_digits_strings(input_list): # 步骤1:筛选纯数字字符串 digit_strings = [item for item in input_list if isinstance(item, str) and item.isdigit()] # 步骤2:拼接结果 return ''.join(digit_strings) # 测试示例 mixed_list = ["123", 456, "abc", "78", "9.0", "0", "xyz"] result = extract_digits_strings(mixed_list) # 输出:"123780" ``` ##### 方法2:正则表达式(处理特殊格式) ```python import re def extract_digits_regex(input_list): result = [] for item in input_list: if isinstance(item, str): # 匹配完整数字字符串(含负号/小数点) match = re.search(r'^-?\d+\.?\d*$', item) if match: result.append(item) return ''.join(result) # 测试包含特殊数字 special_list = ["-123", "45.6", "78", "abc", "0.99"] print(extract_digits_regex(special_list)) # 输出:"-12345.6780.99" ``` #### 关点说明 1. **类型判断**:`isinstance(item, str)`确保只处理字符串类型 2. **纯数字检测**: - `isdigit()`:仅识别正整数字符串(如"123") - 正则`r'^-?\d+\.?\d*$'`:识别负数/小数(如"-1.23") 3. **拼接处理**:`''.join()`高效连接字符串列表 #### 测试用例 | 输入列表 | 输出结果 | 说明 | |----------|----------|------| | `["12", "ab", 34]` | `"12"` | 过滤非字符串和非法字符串 | | `["0", "1.5", "-2"]` | `"0"` | 默认只识别正整数 | | `["100", "200", "300"]` | `"100200300"` | 多字符串拼接 | | `[]` | `""` | 空列表处理 | #### 常见问题处理 1. **包含前导零的数字**: ```python extract_digits_strings(["007", "08"]) # 输出:"00708" ``` 2. **科学计数法数字**: ```python # 扩展正则表达式 re.search(r'^-?\d+(?:\.\d*)?(?:[eE][-+]?\d+)?$', "1.23e-4") ``` #### 性能建议 - **小型列表**:使用`isdigit()`方法(时间复杂度$O(n)$) - **大型数据**:正则表达式预编译优化: ```python pattern = re.compile(r'^-?\d+\.?\d*$') [item for item in input_list if pattern.match(item)] ``` #### 相关问题拓展 1. 如何同时提取字符串中的数字和列表中的数字类型? 2. 当数字字符串包含千分位分隔符(如"1,000")时如何处理? 3. 如何优化超大型列表(百万级元素)的处理效率? 4. 是否存在并行化处理方案加速提取过程?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值