• — Можно ли миллион записать в один бит?
    — Конечно: 1 — есть миллион, 0 — нет миллиона…

Программа частотного анализа текста

Исходная задача:

На вход программе подается последовательность символов, заканчивающаяся символом #.
Другие символы # во входной последовательности отсутствуют.
Программа должна вывести на экран символы латинского алфавита, в порядке увеличения частоты встречаемости во входной последовательности.
Если буква во входной последовательности не встречается, ее выводить не нужно.
Если несколько букв встречаются одинаковое количество раз, программа должна вывести их в алфавитном порядке.
Строчные и прописные буквы не различаются.

Пример входных данных:
Aced, ccedaa f#
Пример выходных данных:
FDEAC

Ссылка на текст программы в  официальном репозитории Microsoft Small Basic: http://smallbasic.com/program/?XKX766

Вы можете скопировать указанный ниже код программы в IDE MS Small Basic и запустить:

'Демонстрационная программа решения задачи C4 средствами Small Basic
'(с) Василий Юрьевич Медведев
'(с) ГБОУ гимназия №70 Петроградского района Санкт-Петербурга
' 2012

'Текст задачи:
'==========================================================
'На вход программе подается последовательность символов, заканчивающаяся символом #.
'Другие символы # во входной последовательности отсутствуют.
'Программа должна вывести на экран символы латинского алфавита,
'в порядке увеличения частоты встречаемости во входной последовательности.
'Если буква во входной последовательности не встречается, ее выводить не нужно.
'Если несколько букв встречаются одинаковое количество раз, программа должна вывести их в алфавитном порядке.
'Строчные и прописные буквы не различаются.
'Напишите эффективную, в том числе и по использованию памяти программу (укажите используемую
'версию языка программирования, например Borland Pascal 7.0), которая должна решать поставленную задачу.
'Пример входных данных:
'Aced, ccedaa f#
'Пример выходных данных:
'FDEAC
'==========================================================
'Для решения данной задачи необходимо подготовить массив счетчиков
'для подсчета количества встретившихся символов

'==========================================================
'Этап ввода исходных данных и подготовки служебных переменных
'Сохраним код символа "A" в переменную, чтобы не вызывать каждый раз функцию получения кода
CodA = Text.GetCharacterCode ("A")
'подготовим (обнулим и инициализируем) массивы счетчиков символов и их номеров
For i = 0 To 25 'всего 26 элементов по количеству символов латинского алфавита
    kol[i] = 0 'индекс начинается от нуля для того, чтобы использовать его в формулах
    codes[i] = CodA+i 'сохраняем коды символов, чтобы после сортировки определить какое количество какому символу соответствует
EndFor
'читаем исходную строку символов
TextWindow.WriteLine ("Введите входную последовательность символов, завершите ее символом #")
InpLine = Text.ConvertToUpperCase(TextWindow.Read()) 'все символы введенной строки сразу переводим в верхний регистр
'Для проверки выведем на экран введенные данные (это необязательный пункт, полезно использовать
'при написании тренировочных программ на ПК, но на экзамене будет лишним, т.к. не несет
'смысловой нагрузки и отнимает время)
TextWindow.WriteLine ("Вы ввели строку:<"+InpLine+"> в этой строке "+(Text.GetLength(InpLine) - 1)+" символ(ов)")
'Проверим корректность введенных данных
'Если пользователь не введет символ #, то может возникнуть ситуация бесконечного цикла)
'Выделяем последний символ в строке и сравниваем с #, если не совпадает, значит произошла
'ошибка ввода и надо завершить программу
If Text.GetSubText(InpLine, (Text.GetLength (InpLine)), 1) <> "#" Then
    TextWindow.WriteLine ("Введены некорректные данные. Строка должна оканчиваться #.Программа будет закрыта")
    TextWindow.Pause() 'пауза, чтобы пользователь успел прочитать предыдущее сообщение
    Program.End() 'команда завершения программы
EndIf
'===========================================================
'Начинаем обработку введенных данных
'==============================================
'Подсчет количества символов в строке
'==============================================
i = 1 'индесксная переменная уже свободна, поэтому можно ее использовать для нового цикла
While Text.GetSubText(InpLine, i, 1) <> "#" 'Выполняем цикл пока не достигнем конца строки
'Выделяем текущий символ и вычисляем его код
    CurCode = Text.GetCharacterCode(Text.GetSubText(InpLine, i, 1))
    'проверяем является ли он символом латинского алфавита
    If (CurCode - CodA >= 0) And (CurCode - CodA < 26) Then
    'Если является, то увеличиваем счетчик соответствующего символа на единицу
        kol[CurCode-CodA]=kol[CurCode-CodA]+1
        'отладочная печать текущего символа на экран
        TextWindow.WriteLine (i+" - "+Text.GetSubText(InpLine, i, 1)+" - "+(CurCode- CodA)) 'отладка, тестовая печать
    EndIf
    'увеличиваем счетчик цикла на единицу для перехода к сследующему символу
    i = i+1
EndWhile
'отладочная печать количества всех встретившихся символов.
For i=0 To 25 
    If kol[i]>0 Then 
        TextWindow.WriteLine ("Символ "+Text.GetCharacter(i+CodA)+" встретился в строке "+kol[i]+" раз(а)") 'отладка, тестовая печать
    EndIf 
EndFor 
'конец отладки
'==============================================
'Сортировка массива количества символов по возрастанию
'==============================================
'для сортировки удобно воспользоваться методом обмена (пузырька)
'этот метод автоматически обеспечит алфавитный порядок вывода символов
'встретившихся одинаковое количество раз
i=24
While i>=0
    For j=0 to i
        If (kol[j] > kol[j+1]) Then
        'перестановка элементов массива счетчиков количества символов
            x = kol[j]
            kol[j] = kol [j+1]
            kol[j+1] = x
            'перестановка элементов массива кодов символов
            x = codes[j]
            codes[j] = codes [j+1]
            codes[j+1] = x
        EndIf
    EndFor
    i=i-1
EndWhile
'==============================================
'Вывод результата на экран
'==============================================
TextWindow.WriteLine ("Результат:")
For i=0 To 25
    If kol[i]>0 Then 'выводим на экран только символы, которые встретились хотя бы 1 раз
        TextWindow.WriteLine ("Символ "+Text.GetCharacter(codes[i])+" встретился в строке "+kol[i]+" раз(а)") 'отладка, тестовая печать
        TextWindow.Write (Text.GetCharacter(codes[i]))
    EndIf
EndFor
TextWindow.WriteLine ("")


Поделиться: