Python基于递归实现电话号码映射功能示例


Posted in Python onApril 13, 2018

本文实例讲述了Python基于递归实现电话号码映射功能。分享给大家供大家参考,具体如下:

问题

电话按键上面的每个数字都对应着几个字母,如果按下一个数字键代表输入一个字母,那么输入一个数字组成的字符串,它所产生的所有的可能的字母串是什么,有多少种

思路:

这个是一个递归的问题

下面是具体的实现,为了更清晰看懂递归调用的过程,这里打印出来了每一次递归的过程:

#!usr/bin/env python
#encoding:utf-8
'''''
__Author__:沂水寒城
功能:电话号码映射
'''
phone_dict={'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'}
def phone_num_map(one_str,phone_dict):
  '''''
  电话号码映射
  '''
  res_list=[]
  deep(one_str, "", res_list)
  return res_list
def deep(one_str, tmp_str, res_list):
  '''''
  递归的遍历过程
  '''
  if not one_str:
    res_list.append(tmp_str)
    return
  for c in phone_dict[one_str[0]]:
    deep(one_str[1:], tmp_str + c, res_list)
    print 'deep({0}, {1}, {2})'.format(one_str[1:], tmp_str + c, res_list)
if __name__ == '__main__':
  one_str_list=['23','567','47','89','44']
  for one_str in one_str_list:
    one_list=phone_num_map(one_str,phone_dict)
    print one_list
    print len(one_list)

结果如下:

deep(, ad, ['ad'])
deep(, ae, ['ad', 'ae'])
deep(, af, ['ad', 'ae', 'af'])
deep(3, a, ['ad', 'ae', 'af'])
deep(, bd, ['ad', 'ae', 'af', 'bd'])
deep(, be, ['ad', 'ae', 'af', 'bd', 'be'])
deep(, bf, ['ad', 'ae', 'af', 'bd', 'be', 'bf'])
deep(3, b, ['ad', 'ae', 'af', 'bd', 'be', 'bf'])
deep(, cd, ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd'])
deep(, ce, ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce'])
deep(, cf, ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf'])
deep(3, c, ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf'])
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']
9
deep(, jmp, ['jmp'])
deep(, jmq, ['jmp', 'jmq'])
deep(, jmr, ['jmp', 'jmq', 'jmr'])
deep(, jms, ['jmp', 'jmq', 'jmr', 'jms'])
deep(7, jm, ['jmp', 'jmq', 'jmr', 'jms'])
deep(, jnp, ['jmp', 'jmq', 'jmr', 'jms', 'jnp'])
deep(, jnq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq'])
deep(, jnr, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr'])
deep(, jns, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns'])
deep(7, jn, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns'])
deep(, jop, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop'])
deep(, joq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq'])
deep(, jor, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor'])
deep(, jos, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos'])
deep(7, jo, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos'])
deep(67, j, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos'])
deep(, kmp, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp'])
deep(, kmq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq'])
deep(, kmr, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr'])
deep(, kms, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms'])
deep(7, km, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms'])
deep(, knp, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp'])
deep(, knq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq'])
deep(, knr, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr'])
deep(, kns, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns'])
deep(7, kn, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns'])
deep(, kop, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop'])
deep(, koq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq'])
deep(, kor, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor'])
deep(, kos, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos'])
deep(7, ko, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos'])
deep(67, k, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos'])
deep(, lmp, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp'])
deep(, lmq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq'])
deep(, lmr, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr'])
deep(, lms, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms'])
deep(7, lm, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms'])
deep(, lnp, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp'])
deep(, lnq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq'])
deep(, lnr, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr'])
deep(, lns, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns'])
deep(7, ln, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns'])
deep(, lop, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop'])
deep(, loq, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq'])
deep(, lor, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq', 'lor'])
deep(, los, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq', 'lor', 'los'])
deep(7, lo, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq', 'lor', 'los'])
deep(67, l, ['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq', 'lor', 'los'])
['jmp', 'jmq', 'jmr', 'jms', 'jnp', 'jnq', 'jnr', 'jns', 'jop', 'joq', 'jor', 'jos', 'kmp', 'kmq', 'kmr', 'kms', 'knp', 'knq', 'knr', 'kns', 'kop', 'koq', 'kor', 'kos', 'lmp', 'lmq', 'lmr', 'lms', 'lnp', 'lnq', 'lnr', 'lns', 'lop', 'loq', 'lor', 'los']
36
deep(, gp, ['gp'])
deep(, gq, ['gp', 'gq'])
deep(, gr, ['gp', 'gq', 'gr'])
deep(, gs, ['gp', 'gq', 'gr', 'gs'])
deep(7, g, ['gp', 'gq', 'gr', 'gs'])
deep(, hp, ['gp', 'gq', 'gr', 'gs', 'hp'])
deep(, hq, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq'])
deep(, hr, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr'])
deep(, hs, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs'])
deep(7, h, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs'])
deep(, ip, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip'])
deep(, iq, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip', 'iq'])
deep(, ir, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip', 'iq', 'ir'])
deep(, is, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip', 'iq', 'ir', 'is'])
deep(7, i, ['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip', 'iq', 'ir', 'is'])
['gp', 'gq', 'gr', 'gs', 'hp', 'hq', 'hr', 'hs', 'ip', 'iq', 'ir', 'is']
12
deep(, tw, ['tw'])
deep(, tx, ['tw', 'tx'])
deep(, ty, ['tw', 'tx', 'ty'])
deep(, tz, ['tw', 'tx', 'ty', 'tz'])
deep(9, t, ['tw', 'tx', 'ty', 'tz'])
deep(, uw, ['tw', 'tx', 'ty', 'tz', 'uw'])
deep(, ux, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux'])
deep(, uy, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy'])
deep(, uz, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz'])
deep(9, u, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz'])
deep(, vw, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw'])
deep(, vx, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw', 'vx'])
deep(, vy, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw', 'vx', 'vy'])
deep(, vz, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw', 'vx', 'vy', 'vz'])
deep(9, v, ['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw', 'vx', 'vy', 'vz'])
['tw', 'tx', 'ty', 'tz', 'uw', 'ux', 'uy', 'uz', 'vw', 'vx', 'vy', 'vz']
12
deep(, gg, ['gg'])
deep(, gh, ['gg', 'gh'])
deep(, gi, ['gg', 'gh', 'gi'])
deep(4, g, ['gg', 'gh', 'gi'])
deep(, hg, ['gg', 'gh', 'gi', 'hg'])
deep(, hh, ['gg', 'gh', 'gi', 'hg', 'hh'])
deep(, hi, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi'])
deep(4, h, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi'])
deep(, ig, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi', 'ig'])
deep(, ih, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi', 'ig', 'ih'])
deep(, ii, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi', 'ig', 'ih', 'ii'])
deep(4, i, ['gg', 'gh', 'gi', 'hg', 'hh', 'hi', 'ig', 'ih', 'ii'])
['gg', 'gh', 'gi', 'hg', 'hh', 'hi', 'ig', 'ih', 'ii']
9
[Finished in 0.4s]

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python 性能优化方法小结
Mar 31 Python
Python使用PIL模块生成随机验证码
Nov 21 Python
python实现教务管理系统
Mar 12 Python
python3.6利用pyinstall打包py为exe的操作实例
Oct 31 Python
对python中大文件的导入与导出方法详解
Dec 28 Python
python实现几种归一化方法(Normalization Method)
Jul 31 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
Aug 05 Python
Python实现图片识别加翻译功能
Dec 26 Python
pytorch 改变tensor尺寸的实现
Jan 03 Python
python中图像通道分离与合并实例
Jan 17 Python
在python中利用pycharm自定义代码块教程(三步搞定)
Apr 15 Python
Python不支持 i ++ 语法的原因解析
Jul 22 Python
Python的多维空数组赋值方法
Apr 13 #Python
python多维数组切片方法
Apr 13 #Python
Python实现判断并移除列表指定位置元素的方法
Apr 13 #Python
Python中的二维数组实例(list与numpy.array)
Apr 13 #Python
对numpy的array和python中自带的list之间相互转化详解
Apr 13 #Python
Pandas中把dataframe转成array的方法
Apr 13 #Python
Python3导入自定义模块的三种方法详解
Apr 13 #Python
You might like
php一个文件搞定微信jssdk配置
2016/12/12 PHP
jquery tab标签页的制作
2010/05/10 Javascript
js中字符替换函数String.replace()使用技巧
2011/08/14 Javascript
jquery 中多条件选择器,相对选择器,层次选择器的区别
2012/07/03 Javascript
jQuery判断checkbox是否选中的小例子
2013/12/02 Javascript
jquery默认校验规则整理
2014/03/24 Javascript
jQuery表单验证功能实例
2015/08/28 Javascript
4种JavaScript实现简单tab选项卡切换的方法
2016/01/06 Javascript
JS实现为排序好的字符串找出重复行的方法
2016/03/02 Javascript
用原生JS对AJAX做简单封装的实例代码
2016/07/13 Javascript
JS+canvas画一个圆锥实例代码
2017/12/13 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
[04:22]DOTA2上海特级锦标赛主赛事第四日TOP10
2016/03/06 DOTA
wxPython学习之主框架实例
2014/09/28 Python
一文总结学习Python的14张思维导图
2017/10/17 Python
python学习之matplotlib绘制散点图实例
2017/12/09 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
python进行两个表格对比的方法
2018/06/27 Python
pytorch 实现在预训练模型的 input上增减通道
2020/01/06 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
keras 模型参数,模型保存,中间结果输出操作
2020/07/06 Python
Born鞋子官网:Born Shoes
2017/04/06 全球购物
瑞典轮胎在线:Tirendo.se
2018/06/21 全球购物
Square Off美国/加拿大:世界上最聪明的国际象棋棋盘
2018/12/06 全球购物
构造方法和其他方法的区别
2016/04/26 面试题
入党积极分子评语
2014/05/04 职场文书
推广普通话标语
2014/06/27 职场文书
安全目标责任书
2014/07/22 职场文书
玩手机检讨书1000字
2014/10/20 职场文书
2015年会计工作总结范文
2015/05/26 职场文书
先进个人主要事迹范文
2015/11/04 职场文书
python保存大型 .mat 数据文件报错超出 IO 限制的操作
2021/05/10 Python
Python pandas读取CSV文件的注意事项(适合新手)
2021/06/20 Python
Python Django获取URL中的数据详解
2021/11/01 Python
Python&Matlab实现樱花的绘制
2022/04/07 Python
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS