funktionierende AC in dezimal

This commit is contained in:
2025-06-25 23:59:18 +02:00
parent 0fbfe58fbb
commit 0ffdf5af24
2 changed files with 62 additions and 24 deletions

View File

@@ -3,7 +3,7 @@ import math
ELEMENTS = []
INTERVALLS = []
N = 32 # länge eines Codeworts
N = 8 # länge eines Codeworts
class Element:
@@ -19,10 +19,10 @@ class Element:
def find_element(list, target_it):
for element in list:
for i, element in enumerate(list):
if element.id == target_it:
return element
return None
return i, element
return None, None
def read_text_file():
@@ -39,34 +39,33 @@ def Z_statistik(message):
m = len(message)
elements = []
global ELEMENTS
for char in message:
entry = find_element(elements, char)
i, entry = find_element(ELEMENTS, char)
if entry is not None:
entry.count += 1
else:
elements.append(Element(char))
ELEMENTS.append(Element(char))
return calculate(elements, m, message)
calculate(m, message)
def calculate(elements, m, message):
def calculate(m, message):
global ELEMENTS
h = 0
for element in elements:
for element in ELEMENTS:
element.p_x_i = element.count / m
element.I_x_i = -1 * math.log2(element.p_x_i)
h += element.p_x_i * element.I_x_i
# Ausgabe
elements.sort(key=lambda element: element.count, reverse=True)
ELEMENTS.sort(key=lambda element: element.count, reverse=True)
"""for element in elements:
print(f"{element.count:3.0f} | {element.p_x_i:10.7f} | {element.I_x_i:10.7f} | »{element.id}«")
print("Entropie = " + h.__str__() + "\n\n")"""
return elements
# --- Aus P1 ---
@@ -79,7 +78,7 @@ def charToBin():
def calcBitCount(block):
p = 1
for char in block:
element = find_element(ELEMENTS, char)
i, element = find_element(ELEMENTS, char)
p *= element.p_x_i
N = round(-math.log(p), 0)
@@ -108,17 +107,56 @@ def createBlocks(message):
block.append(char)
else:
blocks.append(block)
block = []
block = [char]
blocks.append(block)
# TODO EOF Symbol setzen und auf Länge des Blocks dabei achten
return blocks
def createCodeWord(block):
intervalls = []
intervall = []
for char in block:
# zeichen für zeichen durch das aktuelle arbeitsintervall wandern und nach jedem Schritt eine Neuberechnung im neuen Teilintervall vornehmen
i, element = find_element(ELEMENTS, block[0])
print(element.id)
if i == 0:
low = 0
else:
low = INTERVALLS[i - 1]
high = INTERVALLS[i]
range = high - low
# Normierung
for i, element in enumerate(ELEMENTS):
new_high = low + range * element.p_x_i
intervalls.append((low, new_high))
low = new_high
print(intervalls)
for char in block[1:]:
i, element = find_element(ELEMENTS, char)
print(element.id)
low, high = intervalls[i]
range = high - low
intervalls = []
for i, element in enumerate(ELEMENTS):
new_high = low + range * element.p_x_i
intervalls.append((low, new_high))
low = new_high
print(intervalls)
low, x = intervalls[0]
x, high = intervalls[-1]
print(f"[{low}, {high})")
def AC_Encoder():
@@ -130,16 +168,16 @@ def AC_Encoder():
l_bin = l * 8
ELEMENTS = Z_statistik(message)
charToBin()
Z_statistik(message)
# charToBin() # unnötig, da nur das Codewort in binär umgewandelt werden muss
calcIntervalls()
# INTERVALLS = [0.1, 0.8, 1]
blocks = createBlocks(message)
print(INTERVALLS)
print(blocks)
createCodeWord(blocks[0])
AC_Encoder()