Сообщество Engee

Выравнивание столбцов

Автор
avatar-maximsidorovmaximsidorov
Notebook

Алгоритм выравнивания столбцов

Этот пример показывает реализацию алгоритма выравнивания текста по столбцам с разными типами выравнивания (влево, вправо, по центру) на языке программирования Julia.

Введение

Алгоритм выравнивания столбцов используется для форматирования текстовых данных, организованных в табличную структуру. Он позволяет создавать красиво отформатированные таблицы, где столбцы выровнены друг относительно друга. Такой подход применяется при выводе отчетов, логов, таблиц и других структурированных данных для улучшения читаемости. В данном примере входные данные представлены в виде текста, где поля разделены символом доллара ($), а строки разделены символом новой строки.

Основная часть

Подготовка данных и вспомогательные функции

Исходный текст с разделителями в виде знака доллара

txt = """Given\$a\$txt\$file\$of\$many\$lines,\$where\$fields\$within\$a\$line\$
are\$delineated\$by\$a\$single\$'dollar'\$character,\$write\$a\$program
that\$aligns\$each\$column\$of\$fields\$by\$ensuring\$that\$words\$in\$each\$
column\$are\$separated\$by\$at\$least\$one\$space.
Further,\$allow\$for\$each\$word\$in\$a\$column\$to\$be\$either\$left\$
justified,\$right\$justified,\$or\$center\$justified\$within\$its\$column.""";

Функции для выравнивания текста разных типов:

# Выравнивание по левому краю: добавляем пробелы справа
ljust(s, width) = s * " "^max(0, width - length(s))

# Выравнивание по правому краю: добавляем пробелы слева
rjust(s, width) = " "^max(0, width - length(s)) * s

# Выравнивание по центру: добавляем пробелы с обеих сторон
function center(s, width)
  pad = width - length(s)  # количество пробелов для заполнения
  if pad <= 0              # если текст уже шире нужной ширины
    return s               # возвращаем как есть
  else
    pad2 = div(pad, 2)     # количество пробелов слева (половина)
    # возвращаем строку с пробелами слева и справа
    return " "^pad2 * s * " "^(pad - pad2)
  end
end
center (generic function with 1 method)

Разбор входных данных

Разделяем текст на строки по символу новой строки \n.

Затем каждую строку разделяем по символу $, \text{предварительно} \text{удаляя} \text{завершающий} $

parts = [split(rstrip(line, '$'), '$') for line in split(txt, '\n')]
# parts теперь содержит массив массивов слов (строки -> столбцы)
6-element Vector{Vector{SubString{String}}}:
 ["Given", "a", "txt", "file", "of", "many", "lines,", "where", "fields", "within", "a", "line"]
 ["are", "delineated", "by", "a", "single", "'dollar'", "character,", "write", "a", "program"]
 ["that", "aligns", "each", "column", "of", "fields", "by", "ensuring", "that", "words", "in", "each"]
 ["column", "are", "separated", "by", "at", "least", "one", "space."]
 ["Further,", "allow", "for", "each", "word", "in", "a", "column", "to", "be", "either", "left"]
 ["justified,", "right", "justified,", "or", "center", "justified", "within", "its", "column."]

Определение максимальной ширины столбцов

Создаем массив для хранения максимальной ширины каждого столбца

Максимальное количество столбцов определяется как максимальная длина строк

max_widths = zeros(Int, maximum(length, parts));

Проходим по всем строкам и определяем максимальную ширину для каждого столбца

for line in parts
  for (i, word) in enumerate(line)
    # Обновляем максимальную ширину для столбца i
    max_widths[i] = max(max_widths[i], length(word))
  end
end   

Добавляем 1 к каждой ширине столбца для обеспечения как минимум одного пробела между столбцами

max_widths .+= 1;

Формирование и вывод результата с разными типами выравнивания

# Проходим по каждому типу выравнивания
for (label, justify) in (("левому краю", ljust), ("правому краю",rjust), ("центру",center))
  # Выводим заголовок для текущего типа выравнивания
  println("Выравнивание по ", label, ":\n")
  
  # Проходим по каждой строке исходных данных
  for line in parts
    # Проходим по каждому слову (столбцу) в строке
    for (j, word) in enumerate(line)
      # Применяем функцию выравнивания к слову с заданной шириной столбца
      print(justify(word, max_widths[j]))
    end
    # Переходим на новую строку после окончания строки данных
    println()
  end
  
  # Выводим разделительную линию из дефисов
  println("-"^sum(max_widths),"\n")
end
Выравнивание по левому краю:

Given      a          txt        file   of     many      lines,     where    fields  within  a      line 
are        delineated by         a      single 'dollar'  character, write    a       program 
that       aligns     each       column of     fields    by         ensuring that    words   in     each 
column     are        separated  by     at     least     one        space.   
Further,   allow      for        each   word   in        a          column   to      be      either left 
justified, right      justified, or     center justified within     its      column. 
---------------------------------------------------------------------------------------------------------

Выравнивание по правому краю:

      Given          a        txt   file     of      many     lines,    where  fields  within      a line
        are delineated         by      a single  'dollar' character,    write       a program
       that     aligns       each column     of    fields         by ensuring    that   words     in each
     column        are  separated     by     at     least        one   space.
   Further,      allow        for   each   word        in          a   column      to      be either left
 justified,      right justified,     or center justified     within      its column.
---------------------------------------------------------------------------------------------------------

Выравнивание по центру:

   Given        a         txt     file    of      many     lines,     where   fields  within    a   line 
    are    delineated     by        a   single  'dollar' character,   write     a    program 
   that      aligns      each    column   of     fields      by     ensuring   that   words    in   each 
  column       are     separated   by     at     least       one     space.  
 Further,     allow       for     each   word      in         a      column     to      be   either left 
justified,    right   justified,   or   center justified   within      its   column. 
---------------------------------------------------------------------------------------------------------

Заключение

В этом примере мы рассмотрели реализацию алгоритма выравнивания текста по столбцам на языке Julia. Нам удалось создать программу, которая принимает текст с разделителями, разбивает его на столбцы, определяет необходимую ширину каждого столбца и выводит отформатированный текст с тремя типами выравнивания: по левому краю, по правому краю и по центру. Это полезно для создания читаемых таблиц и отчетов в текстовом формате, а также демонстрирует основы работы с текстовыми данными и форматированием строк в языке Julia.

Пример разработан с использованием материалов Rosetta Code