main
3wish 2023-11-29 19:31:30 +08:00
commit b34bc34143
19 changed files with 354 additions and 0 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
.venv
test/.pytest_cache/

3
.idea/.gitignore vendored 100644
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,31 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="18">
<item index="0" class="java.lang.String" itemvalue="autoflake" />
<item index="1" class="java.lang.String" itemvalue="pytest" />
<item index="2" class="java.lang.String" itemvalue="pytest-cov" />
<item index="3" class="java.lang.String" itemvalue="mypy" />
<item index="4" class="java.lang.String" itemvalue="black" />
<item index="5" class="java.lang.String" itemvalue="h11" />
<item index="6" class="java.lang.String" itemvalue="isort" />
<item index="7" class="java.lang.String" itemvalue="pytest-asyncio" />
<item index="8" class="java.lang.String" itemvalue="codecov" />
<item index="9" class="java.lang.String" itemvalue="pandas" />
<item index="10" class="java.lang.String" itemvalue="Django" />
<item index="11" class="java.lang.String" itemvalue="SQLAlchemy" />
<item index="12" class="java.lang.String" itemvalue="DBUtils" />
<item index="13" class="java.lang.String" itemvalue="openpyxl-3.1.2" />
<item index="14" class="java.lang.String" itemvalue="PyMySQL" />
<item index="15" class="java.lang.String" itemvalue="uwsgi" />
<item index="16" class="java.lang.String" itemvalue="djangorestframework" />
<item index="17" class="java.lang.String" itemvalue="django-cors-headers" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml 100644
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (pygorithm)" project-jdk-type="Python SDK" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pygorithm.iml" filepath="$PROJECT_DIR$/.idea/pygorithm.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.11 (pygorithm)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

12
Pipfile 100644
View File

@ -0,0 +1,12 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pytest = "*"
[dev-packages]
[requires]
python_version = "3.11"

61
Pipfile.lock generated 100644
View File

@ -0,0 +1,61 @@
{
"_meta": {
"hash": {
"sha256": "922e82e69ac92d524e9aec65cbead9fdef4cdb3fcff8f459d8998bfd7bd6a67f"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.11"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"colorama": {
"hashes": [
"sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44",
"sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
],
"markers": "sys_platform == 'win32'",
"version": "==0.4.6"
},
"iniconfig": {
"hashes": [
"sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3",
"sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"
],
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
},
"packaging": {
"hashes": [
"sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
],
"markers": "python_version >= '3.7'",
"version": "==23.2"
},
"pluggy": {
"hashes": [
"sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12",
"sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
],
"markers": "python_version >= '3.8'",
"version": "==1.3.0"
},
"pytest": {
"hashes": [
"sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac",
"sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"
],
"index": "pypi",
"version": "==7.4.3"
}
},
"develop": {}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,78 @@
"""
1. 经观察可发现操作数的相对位置是不变的变化的只是操作符
2. 中转前
1 如果是一个操作数则看一眼操作符栈中的栈顶是否是 */
1.1. 如果是 */则先拿到这个操作数再从操作数栈弹出一个数
再弹出操作符拼接后放入操作数栈顶
1.2如果是 +-则将此操作数入操作数栈
2. 如果是一个 ( + - * /直接入操作符栈顶
3. 如果是 )则执行出栈直到遇到 (出栈的步骤跟 1.1
3. 中转后
1.
"""
from .stack import Stack
def infix_to_prefix(infix: str):
op_stack = Stack[str]()
num_stack = Stack[str]()
for item in infix:
if item in ['(', '*', '+', '-', '/']:
op_stack.push(item)
elif '0' <= item <= 'z':
if op_stack.peek() in ['*', '/']:
temp = num_stack.pop()
op = op_stack.pop()
num_stack.push(op + temp + item)
else:
num_stack.push(item)
elif item == ')':
op = op_stack.pop()
while op != '(':
temp1 = num_stack.pop()
temp2 = num_stack.pop()
num_stack.push(op + temp2 + temp1)
op = op_stack.pop()
if not op_stack.is_empty():
i1 = num_stack.pop()
i2 = num_stack.pop()
op = op_stack.pop()
return op + i2 + i1
else:
return num_stack.pop()
def infix_to_postfix(infix: str):
op_stack = Stack[str]()
num_stack = Stack[str]()
for item in infix:
if item in ['(', '*', '+', '-', '/']:
op_stack.push(item)
elif '0' <= item <= 'z':
if op_stack.peek() in ['*', '/']:
temp = num_stack.pop()
op = op_stack.pop()
num_stack.push(temp + item + op)
else:
num_stack.push(item)
elif item == ')':
op = op_stack.pop()
while op != '(':
temp1 = num_stack.pop()
temp2 = num_stack.pop()
num_stack.push(temp2 + temp1 + op)
op = op_stack.pop()
if not op_stack.is_empty():
i1 = num_stack.pop()
i2 = num_stack.pop()
op = op_stack.pop()
return i2 + i1 + op
else:
return num_stack.pop()
res = infix_to_prefix('a+b*c')
print(res)

View File

@ -0,0 +1,24 @@
"""
进制转换
1. 将十进制转换为二十六进制
2. 对2取余余数存入栈中
3. 将取余得的商重复第2步直到商为零
4. 将栈中的数取出即是转换为二进制的结果
"""
from .stack import Stack
def decimal_to_any(num: int, base: 2 | 8 | 16) -> str:
stack = Stack[str]()
while num > 0:
mod: int = num % base
num //= base
stack.push(str(mod))
res = ''
while not stack.is_empty():
res += stack.pop()
return res

View File

@ -0,0 +1,27 @@
"""
测试括号是否匹配
1. 左括号数必须与右括号数匹配
2. 从左到右匹配用栈保存每个左括号
3. 每遇到一个右括号则左括号执行出栈操作
4. 匹配成功结束时若栈空则
5. 匹配失败栈未空 > 或者在结束之前栈已空 >
"""
from .stack import Stack
def par_match(parentheses: str) -> bool:
stack = Stack[str]()
for i in parentheses:
if i == '(':
stack.push(i)
elif i == ')':
if stack.is_empty():
return False
stack.pop()
if stack.is_empty():
return True
else:
return False

32
stack/stack.py 100644
View File

@ -0,0 +1,32 @@
from typing import Generic, TypeVar
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self):
self.top: int = 0
self.data: list[T] = []
def push(self, value: T):
self.data.append(value)
self.top += 1
def pop(self) -> T | None:
if self.top > 0:
self.top -= 1
return self.data.pop()
else:
return None
def peek(self) -> T | None:
if self.top > 0:
return self.data[self.top - 1]
else:
return None
def is_empty(self) -> bool:
return self.top == 0
def size(self) -> int:
return self.top

58
test/test_stack.py 100644
View File

@ -0,0 +1,58 @@
from stack.parentheses import par_match
from stack.number_conversion import decimal_to_any
from stack.infix_conversion import infix_to_prefix, infix_to_postfix
def test_par_match1():
parentheses = '((()))(()()'
assert not par_match(parentheses)
def test_par_match2():
parentheses = '((()))(())'
assert par_match(parentheses)
def test_par_match3():
parentheses = '(((5+3)))*((4-2))'
assert par_match(parentheses)
def test_to_binary1():
num = 5
assert decimal_to_any(num, 2) == '101'
def test_to_binary2():
num = 10
assert decimal_to_any(num, 2) == '1010'
def test_infix_to_prefix():
infix = 'a+b*c'
assert infix_to_prefix(infix) == '+a*bc'
def test_infix_to_prefix_with_parentheses1():
infix = '(a+b)*c'
assert infix_to_prefix(infix) == '*+abc'
def test_infix_to_prefix_with_parentheses2():
infix = '(a+b)*(c-d)'
assert infix_to_prefix(infix) == '*+ab-cd'
def test_infix_to_postfix():
infix = 'a+b*c'
assert infix_to_postfix(infix) == 'abc*+'
def test_infix_to_postfix_with_parentheses1():
infix = '(a+b)*c'
assert infix_to_postfix(infix) == 'ab+c*'
def test_infix_to_postfix_with_parentheses2():
infix = '(a+b)/(c-d)'
assert infix_to_postfix(infix) == 'ab+cd-/'