Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Русский_Проект: Изучение Visual Basic


Информационный Канал Subscribe.Ru

Русский_Проект: Рассылка Разбор прошлых заданий
Задачки
Советы
Функции Windows API

Разбор прошлых заданий

И снова разбираем позапрошлое задание. Напомним условие. Определить, сколько существует вариантов дать сдачу 27 рублей монетами в 1, 2 и 5 рублей так, чтобы общее количество монет было равно 10
Мы уже смогли улучшить программу. Но и это не предел. Если нам известно количество монет i и j, то число k вычисляется как разность k = 10 - i - j. Подставляем это равенство вместо k и получаем, что
a = i * 5 + j * 2 + k * 1=i * 5 + j * 2 + (10 - i - j * 1)=10 + 4 * i + j
тем самым мы убираем один внутренний цикл для переменной k и немного изменяем проверочное условие
' Новое решение
 ' Пусть i - 5 руб. j - 2 руб. k - 1 руб
 For i = 0 To 5
 For j = 0 To 10
 a = i * 4 + j + 10

 If a = 27 And 10 - i - j >= 0 Then Debug.Print i, j, 10 - i - j
 Next j, i
Тем самым, мы сократили намного количество переборок. Данное решение прислал Алексей Михеев (avmiheev@...). За что ему большое спасибо!

Теперь разберем задачу на перестановки. Итак, даны 5 букв. Нужно из них составить все возможные слова
Многие стали решать задачу в "лоб", перебирая все возможные перестановки во вложенные циклах. Давайте посчитаем. Мы уже знаем, что из 5 элементов получаются 5!=120 перестановок. Пять вложенные циклов дают 5*5*5*5*5=3125 вариантов. (Здесь некоторые остановились, посчитав задачу выполненой. Но, вариант "aaaaa" не является правильным, т.к. у нас нет 5 букв "а"). Остальные пошли дальше. Отбрасываем комбинации с одинаковыми буквами и получаем 120 вариантов. Но сколько лишней работы. Нам нужно составить алгоритм, основанный не на прямом переборе, а на направленном формировании нужных перестановок. Вот какое письмо получил от Владимира Кирко (vlyrki@...)

Поскольку, в общем случае, задачка нетривиальная, то я позволил себе
воспользоваться общеизвестными алгоритмами.
Function NextPerm(N As Integer, p As Variant) As Integer
'Функция реализует следующую перестановку в массиве p и
'возвращает: 0  - если не все перестановки реализованы,
'                     -1 - перебор перестановок закончен
'(Алгоритм заимствован
'с
http://world.fpm.kubsu.ru/krasnodar/computers_programmings/algoritms/n!.htm)
 Dim i As Integer, j As Integer, k As Integer, z As Integer, tmp As Integer
 i = N - 2
 While p(i) >= p(i + 1)
  If i = 0 Then
    NextPerm = -1: Exit Function 'последняя перестановка, возврат -1
  End If
  i = i - 1
 Wend
 j = N - 1
 While p(j) <= p(i): j = j - 1: Wend
 tmp = p(i): p(i) = p(j): p(j) = tmp 'меняем местами i-ый и j-ый элементы
 z = N - 1
 For k = i + 1 To i + (N - i - 1) / 2
  tmp = p(z): p(z) = p(k): p(k) = tmp 'меняем местами z-ый и k-ый элементы
  z = z - 1
 Next k
 NextPerm = 0
End Function

Private Sub Form_Load()
'Переставлять будем последовательность 0 - (N-1), символы подставим в конце.
Dim sym, i, k
Dim N As Integer, count As Integer, res As String
Dim p() As Integer      'динамический массив
 N = 5          'число переставляемых элементов
 sym = Array("a", "b", "c", "i", "s") 'сами элементы
 ReDim p(N - 1)   'в случае, если из из этого захочется сделать процедуру
 For i = 0 To N - 1
  p(i) = i + 1    'инициализация массива значениями 0,1, ...N-1
 Next i

 count = 0   'для нумерации строчек вывода
 Do
 'подготовка печати результата
  count = count + 1
  res = CStr(count) & "." & vbTab
  For k = 0 To N - 1
   'res = res & sym(p(k) - 1) & IIf(k = N - 1, "", ", ") 'печать элементов через запятую
   res = res & sym(p(k) - 1)       'печать элементов сплошняком
  Next k
 'конец подготовки печати результата
  Debug.Print res   'печать результата (30 строчка вывода в окне отладки будет - basic)
 Loop While NextPerm(N, p) <> -1

End Sub

Задачки

Рубрика для любителей решать задачки.
Отложим на время комбинаторику. Сегодня займемся вращением по кругу. Для некоторых это является проблемой. Попробуйте изобразить вращение луны вокруг земли. Точнее, маленькой окружности вокруг большой. Здесь надо вспомнить математику. Координаты точки при вращении меняются по формуле
x = R * Sin(A)
y = R * Cos(A)
, где R - радиус окружности вращения, A - угол поворота в радианах против часовой стрелки. Ваша задача, используя эти формулы заставить маленький кружочек вращаться по часовой стрелке. Ваши решения принимаются только с комментариями!
Решения задачи можете присылать по адресам vbasic@rambler.ru или wwwind@aport.ru

Советы

Регулярные выражения можно использовать и в среде разработки Visual Basic. А именно в окне поиска (Edit-Find). Предположим ваш код содержит имена переменных Command1, Command2, Command3, Command4 и т.д. Вы с помощью поиска хотите найти только слова Command1 и Command2, но не хотите искать Command3, Command4. Традиционный способ поиска по шаблону Command здесь не подойдет, так как будут найдены все слова. Здесь на помощь придут регулярные выражения. Впишите в поле поиска выражение Command[12] и поставьте галочку в Use Pattern Matching.
И будут найдены только слова Command1 и Command2. Можете использовать и другие символы регулярных выражений. Например, Command[!1-3] позволит найти любые слова Command c цифрами от 4 и далее, но не Command1, Command2, Command3!

Функции API

Функция midiOutShortMsg

Функция midiOutShortMsg посылает короткое сообщение заданному MIDI-устройству

Параметры

lphMidiOut
Указатель на дескриптор HMIDIOUT, который служит для идентификации открытого MIDI-устройства. Необходим при вызовах других MIDI-функций
dwMsg
MIDI-сообщение Возвращаемое значение
В успешном случае функция возвращает MMSYSERR_NOERROR. В случае ошибки может вернуть код ошибки, например MIDIERR_BADOPENMODE, MIDIERR_NOTREADY, MMSYSERR_INVALHANDLE

Пример

' Сыграем простую мелодию
' Добавим в General Declaration глобальную переменную
Dim hMIDI As Long

' Добавим две процедуры
Public Sub NoteOn(ByVal Note As Long)
midiOutShortMsg hMIDI, &H5A0090 + Note * &H100&
End Sub

Public Sub NoteOff(ByVal Note As Long)
midiOutShortMsg hMIDI, &H90& + Note * &H100&
End Sub

' Играем мелодию
Dim DeviceID As Long

DeviceID = -1

midiOutOpen hMIDI, DeviceID, 0&, 0&, 0&
NoteOn (70)
Sleep (900)
NoteOff (70)

NoteOn (90)
Sleep (900)
NoteOff (90)


NoteOn (64)
Sleep (400)
NoteOff (64)

NoteOn (64)
Sleep (900)
NoteOff (64)

NoteOn (67)
Sleep (900)
NoteOff (67)

NoteOn (70)
Sleep (900)
NoteOff (70)
Полный текст с описанием этой функции вы найдете в справочнике по функциям Windows API Примечание
При описании данной функции использовалась статья с сайта VBMania о лаборантках. Рекомендую поближе ознакомиться с данной статьей и прилагаемым примером, в котором используются интересные приемы программирования. В частности, создание проекта без формы. Безусловно, данный сайт является одним из лучших среди русскоязычных ресурсов по бейсику. К сожалению, нерегулярность выхода новых материалов в данном онлайн-журнале весьма отрицательно сказывается на репутации авторов журнала. А жаль. Если у вас есть интересные идеи, присылайте им. Не дайте им засохнуть :-)

Не стесняйтесь, высылайте ваши предложения по адресу vbasic@rambler.ru
Посетите сайт Русский_Проект, где вы найдете другую интересную информацию
Давайте делать рассылку вместе! Удачи!



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное