最近干活的时候遇到了从驼峰命名的样式转换为css版本的短线命名,记录一下这里用到的算法。
问题描述
将给定的字符串中以大写字母做分隔的字符串变为以短线分隔,非大写字母均认为是小写字母
。
思路
思路:
1. 查找大写的位置,相邻的位置合并,被合并的大写位置变小写
2. 剩下的大写索引位置插入’-',同时大写变小写
复杂度:
O
(
N
)
O(N)
O(N)
实现
def chg_to_short_line(hump: str):
"""
类驼峰转短线连接
:param hump: 类驼峰名
:return: 短线连接名
"""
if hump is None:
raise TypeError("""'NoneType' object is not convertible.""")
pass
# 扫描大写位置
process_hump = list(hump)
# big idx stack
big_idx = []
i = 0
# 是否相邻的标志位
between = False
# 如果相邻用来暂存上一个大写的索引
between_val = None
for c in process_hump:
if 65 <= ord(c) <= 90:
if len(big_idx) != 0:
# 判断相邻而决定待比较的<上一个>应该为 <栈顶> 还是 <大写相邻的特殊情况>
if between:
pre = between_val
pass
else:
# 没相邻则为big_idx栈顶
pre = big_idx[-1]
pass
if i - pre == 1:
# 出现相邻则合并 原位置调整为小写
process_hump[i] = c.lower()
# 标记相邻
between = True
between_val = i
pass
else:
# 不相邻的情况重置标志位
between = False
between_val = None
big_idx.append(i)
pass
else:
# 栈空时不存在相邻大写的判断,直接入栈
between = False
between_val = None
big_idx.append(i)
pass
else:
if between and len(big_idx) != 0:
# 如果已经处理到小写而当前标志位是True时,说明目前最后一个大写也被转换小写了,反转这一操作。
process_hump[i - 1] = process_hump[i - 1].upper()
big_idx.append(i - 1)
between = False
between_val = None
pass
i += 1
# 最后big_idx处理,插入短线
#
# ext_pos 为首位不插入短线而占位
ext_pos = 0
for idx in range(len(big_idx)):
idx_val = big_idx[idx]
process_pos = int(idx_val + idx - ext_pos)
process_hump[process_pos] = process_hump[process_pos].lower()
if process_pos != 0:
# 非第一位插入短线
# FIXME: 这里list的数组结构影响insert效率问题
process_hump.insert(process_pos, '-')
else:
ext_pos += 1
pass
return "".join(process_hump)