Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Kölner Phonetik (Zeichenketten)

Die Kölner Phonetik liefert, ähnlich dem anglophonen Soundex ein phonetisches Muster, um ähnlich klingende Wörter aufzuspüren und sichtbar zu machen.

Ihre Aufgabe:
Schreiben Sie eine Routine, die für eine Eingabe den entsprechenenden Code in Kölner Phonetik ausgibt.
Durchsuchen Sie dann das wohlbekannte Wörterbuch auf das  Muster: 30406 und listen Sie die Ergebnisse.

1 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

Kommentare (1)

virgil 10. März 2023 22:39   reply report
Das »Wohlbekannte Wörterbuch ist hier:
https://www.programmieraufgaben.ch/uploads/attachements/ed26176ae825.zip

3 Lösung(en)

// C++ 14 | VS-2022
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <string>
#include <fstream>

using _str = std::string;
using namespace std::string_literals;

inline const _str convert_char_to_num(char prev_, char act_, char next_, bool is_first_) {
    auto next = std::toupper(next_);
    auto prev = std::toupper(prev_);

    switch (std::toupper(act_)) {
    case 'A':
    case 'Ä':
    case 'E':
    case 'I':
    case 'J':
    case 'O':
    case 'Ö':
    case 'U':
    case 'Ü':
    case 'Y': return "0";
    case 'H': return "";
    case 'B': return "1";
    case 'P': return next != 'H' ? "1" : "3";
    case 'D':
    case 'T': return ("CSZ"s.find(next) == _str::npos) ? "2" : "8";
    case 'F':
    case 'V':
    case 'W': return "3";
    case 'G':
    case 'K':
    case 'Q': return "4";
    case 'C': return (prev == 'S' || prev == 'Z' || 
                is_first_ && "AHKLOQRUX"s.find(next) == _str::npos ||
                "AHKOQUX"s.find(next) == _str::npos) ? "8" : "4";
    case 'X': return "CKQ"s.find(next) == _str::npos ? "48" : "8";
    case 'L': return "5";
    case 'M':
    case 'N': return "6";
    case 'R': return "7";
    case 'S':
    case 'ß':
    case 'Z': return "8";
    default: return "";
    }
}

inline const _str convert_string_to_num(const _str& str_) {
    std::stringstream sstr;
    if (str_.length() == 0) return "";
    sstr << convert_char_to_num('\0', str_[0], str_[1], true);
    size_t i{ 1 };
    for (; i < str_.length() - 1; ++i)
        sstr << convert_char_to_num(str_[i - 1], str_[i], str_[i + 1], false);
    sstr << convert_char_to_num(str_[i - 1], str_[i], '\0', false);
    return sstr.str();
}

inline const _str remove_zeros_except_first(const _str& str_) {
    auto str{ str_ };
    if (str_.length() == 0) return "";
    const auto it{ std::remove(str.begin() + 1, str.end(), '0') };
    str.erase(it, str.end());
    return str;
}

inline const _str remove_doubles(const _str& str_) {
    _str out{};
    if (str_.length() == 0) return "";
    for (size_t i{ 0 }; i < str_.length(); ++i) {
        out.push_back(str_[i]);
        while (str_[i] == str_[i + 1]) i++;
    }
    return out;
}

inline const _str get_cologne_phonetic(const _str& str_) {
    return remove_doubles(remove_zeros_except_first(convert_string_to_num(str_)));
}

int main() {

    // Aufgabe 1:
    std::cout << get_cologne_phonetic("Wikipedia"s) << "\n"; // 3412
    std::cout << get_cologne_phonetic("Breschnew"s) << "\n"; // 17863
    std::cout << get_cologne_phonetic("Müller-Lüdenscheidt"s) << "\n"; // 65752682

    // Aufgabe 2:
    // funktioniert aber nur bedingt, da sich C++ mit Umlauten sehr schwer tut
    const auto comp{ "30406"s };
    const auto path{ "C:\\...\\deutsch.txt"s};

    _str line;
    std::ifstream input(path);

    if (!input) {
        std::cerr << "Pfad nicht gefunden: " << path<< "\n";
        return 1;
    }

    while (std::getline(input, line)) {
        if (get_cologne_phonetic(line) == comp)
            std::cout << line << "\n";
    }
}
                

Lösung von: Jens Kelm (@JKooP)

// NET 7.x | C# 11.x | VS-2022

string ConvertCharToNum(char prev, char act, char next, bool is_first) => 
    (char.ToUpper(prev), char.ToUpper(act), char.ToUpper(next), is_first) switch {
    (_, 'A' or 'Ä' or 'E' or 'I' or 'J' or 'O' or 'U' or 'Ü' or 'Y', _, _) => "0",
    (_, 'H', _, _) => string.Empty,
    (_, 'B', _, _) => "1",
    (_, 'P', not 'H', _) => "1",
    (_, 'P', 'H', _) => "3",
    (_, 'D' or 'T', not ('C' or 'S' or 'Z'), _) => "2",
    (_, 'D' or 'T', 'C' or 'S' or 'Z', _) => "8",
    (_, 'F' or 'V' or 'W', _, _) => "3",
    (_, 'G' or 'K' or 'Q', _, _) => "4",
    ('S' or 'Z', 'C', _, _) => "8",
    (_, 'C', not ('A' or 'H' or 'K' or 'L' or 'O' or 'Q' or 'R' or 'U' or 'X'), true) => "8",
    (_, 'C', not ('A' or 'H' or 'K' or 'O' or 'Q' or 'U' or 'X'), _) => "8",
    (_, 'C', _, _) => "4",
    (_, 'X', not ('C' or 'K' or 'Q'), _) => "48",
    (_, 'X', _, _) => "8",
    (_, 'L', _, _) => "5",
    (_, 'M' or 'N', _, _) => "6",
    (_, 'R', _, _) => "7",
    (_, 'S' or 'ß' or 'Z', _, _) => "8",
    (_, _, _, _) => string.Empty
};

string ConvertStringToNum(string str) {
    var output = string.Empty;
    var len = str.Length;
    if (len == 0) return string.Empty;
    output += ConvertCharToNum('\0', str[0], str[1], true);
    var i = 1;
    for (; i < len - 1; ++i)
        output += ConvertCharToNum(str[i - 1], str[i], str[i + 1], false);
    output += ConvertCharToNum(str[i - 1], str[i], '\0', false);
    return output;
}

string RemoveZerosExceptFirst(string str) {
    if (str.Length == 0) return string.Empty;
    return (str[0] == '0' ? "0" : string.Empty) + string.Join(string.Empty, str.Where(x => x != '0').ToArray());
}

string RemoveDoubles(string str) {
    var len = str.Length;
    if (len == 0) return string.Empty;
    var output = string.Empty;
    for (var i = 0; i < len; i++) {
        output += str[i];
        while (i + 1 < len && str[i] == str[i + 1]) i++;
    }
    return output;
}

string GetColognePhonetic(string str) =>
    RemoveDoubles(RemoveZerosExceptFirst(ConvertStringToNum(str)));

Console.WriteLine(GetColognePhonetic("Wikipedia")); // 3412
Console.WriteLine(GetColognePhonetic("Breschnew")); // 17863
Console.WriteLine(GetColognePhonetic("Müller-Lüdenscheidt")); // 65752682
                

Lösung von: Jens Kelm (@JKooP)

' VBA
Function ConvertCharToNum(prev_ As String, act_ As String, next_ As String, isFirst_ As Boolean) As String
    prev_ = UCase(prev_)
    next_ = UCase(next_)
    Dim res As String
    Select Case UCase(act_)
        Case "A", "Ä", "E", "I", "J", "O", "Ö", "U", "Ü", "Y": res = "0"
        Case "H": res = ""
        Case "B": res = "1"
        Case "P": res = IIf(next_ <> "H", "1", "3")
        Case "D", "T": res = IIf(InStr("CSZ", next_) = 0, "2", "8")
        Case "F", "V", "W": res = "3"
        Case "G", "K", "Q": res = "4"
        Case "C": res = IIf(prev_ = "S" Or prev_ = "Z" Or isFirst_ _
            And InStr("AHKLOQRUX", next_) = 0 Or InStr("HKOQUX", next_) = 0, "8", "4")
        Case "X": res = IIf(InStr("CKQ", next_) = 0, "48", "8")
        Case "L": res = "5"
        Case "M", "N": res = "6"
        Case "R": res = "7"
        Case "S", "ß", "Z": res = "8"
        Case Else: res = ""
    End Select
    ConvertCharToNum = res
End Function

Function ConvertStringToNum(str_ As String) As String
    If Len(str_) = 0 Then ConvertStringToNum = "": Exit Function
    Dim res As String
    Dim i As Integer
    res = ConvertCharToNum("\0", Mid(str_, 1, 1), Mid(str_, 2, 1), True)
    For i = 2 To Len(str_) - 1
        res = res + ConvertCharToNum(Mid(str_, i - 1, 1), Mid(str_, i, 1), Mid(str_, i + 1, 1), False)
    Next
    res = res + ConvertCharToNum(Mid(str_, i - 1, 1), Mid(str_, i, 1), "\0", False)
    ConvertStringToNum = res
End Function

Function RemoveZerosExceptFirst(str_ As String) As String
    If Len(str_) = 0 Then RemoveZerosExceptFirst = "": Exit Function
    Dim res As String
    Dim i As Integer
    res = Mid(str_, 1, 1)
    For i = 2 To Len(str_)
        If Mid(str_, i, 1) <> "0" Then
            res = res + Mid(str_, i, 1)
        End If
    Next
    RemoveZerosExceptFirst = res
End Function

Function RemoveDoubles(str_ As String) As String
    If Len(str_) = 0 Then RemoveDoubles = "": Exit Function
    Dim res As String
    Dim i As Integer
    For i = 1 To Len(str_)
        res = res + Mid(str_, i, 1)
        Do While Mid(str_, i, 1) = Mid(str_, i + 1, 1)
            i = i + 1
        Loop
    Next
    RemoveDoubles = res
End Function

Function GetColognePhonetic(str_ As String) As String
    GetColognePhonetic = RemoveDoubles(RemoveZerosExceptFirst(ConvertStringToNum(str_)))
End Function

Sub Main()
    Debug.Print GetColognePhonetic("Wikipedia") '3412
    Debug.Print GetColognePhonetic("Breschnew") '17863
    Debug.Print GetColognePhonetic("Müller-Lüdenscheidt") '65752682
End Sub
                

Lösung von: Jens Kelm (@JKooP)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 1
Schwierigkeit: Mittel
Webcode: 7iuk-2dwi
Autor: ()

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen