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

Программирование с нуля - это совсем просто! 40) Промежуточные итоги


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

 
Школа программирования

Программирование с нуля - это совсем просто!

40) Промежуточные итоги

Это предложение содержит капуста шесть слов.

К Новому Году, за семестр, и за 40 выпусков, мы изучили все основные понятия программирования. Что-то в теории, что-то не до конца, но, подчеркну еще раз, ЛЮБОЙ алгоритм, любую программу из тех, что вы пользуете, можно написать с помощью несложного набора - оператора присваивания, условного оператора, оператора цикла, понятия подпрограмм и массивов. Причем подпрограммы, массивы, типы данных - вещи уже скорее более нужные для удобства разработчика. Точно так же понятие объекта (объединение свойств и методов, переменных и подпрограмм), с которым мы пока в теории познакомились, создано для удобства прежде всего. Просто, чтобы удобством пользоваться, это удобство надо сначала изучить :)

Закинул старик невод..
Тянет, а ему оттуда:
-СЕТЬ ВРЕМЕННО НЕДОСТУПНА.

* Работа с символами в Бейсике:

В Бейсике (как в .NET, так и в старом) можно сделать так:
подстрока: Mid(str As String, Start As Integer, Length As Integer) As String
ASCII код: Asc(str As String) As Integer
Unicode код: AscW (str As String) As Integer
Символ из ASCII кода: Chr(CharCode As Integer) As Char
Символ из Unicode кода: ChrW(CharCode As Integer) As Char
Леонид

* Как все-таки сделать так, чтобы выпадали действительно случайные числа?
Екатерина

Чтобы не повторялись одни и те же последовательности? Надо в начале один раз вызвать процедуру

Randomize;

в Си:

randomize();

в любом месте до первого вызова random, тогда при каждом новом запуске программ будет новая случайная последовательность выдаваться. Если же отлаживаем, то рандомайз можно закомментировать временно, чтобы на известной последовательности программу отладить.

У мужчины в Санкт-Петербурге спрашивают:
- Какова вероятность того, что, выйдя на Невский проспект, вы встретите динозавра?
- Меньше одной миллиардной.
У женщины - тот же вопрос. Ответ:
- Одна вторая.
- Как это???
- Ну либо встречу, либо не встречу...

* Об отладке графических программ по шагам. С начала, конечно, F8 не будет работать, это в консольной, вся программа была от начала до конца, а тут куча вспомогательного кода, сгенерированного автоматически, поэтому:

Можно, в принципе F5 сделать, значения посмотреть, но когда ошибка какая-нибудь вылезает, хочется же по шагам посмотреть. На все строчки F5 что ли ставить?

Смотрите, где ошибка вылезает, и ставите F5 на предыдущий оператор. Это гораздо удобнее, чем по шагам с начала в ГУИ :)

Что такое "пи"?
Математик: Пи - это число, равное отношению между длиной окружности и ее диаметром.
Физик: Пи - это 3.1415927 + 0.0000005
Инженер: Пи - это что-то около 3.

А программист? Наверное, константа pi (проверьте, по-моему должна быть такая стандартная в модуле Math :).

   uses Math;
   var x;
   begin
   x := 2 * pi ;
   writeln(x);
   readln;
   end;

Несколько решений.

По поводу подпрограмм на Си, давно я это письмо Андрея хранил, и вот наконец подошло время. Пример, как аккуратно функции использовать.

Теперь - решение Вашей задачи №10, хороший пример области видимоти имён и, кстати, потокового вывода (взяты в поток строка, тип float, строка, тип int и т.д.):

  #include <iostream.h>
  #include <conio.h>
  //-------------------------------------------------------------------
  /* Functions ' definition: */
  //-------------------------------------------------------------------
  float fPositivePower (float fBasis, int nPower) // Вычисляет
                                                 // положительную
                                                 // степень числа.
  {
    float fResult=1;
    while( nPower>0)
    {
      fResult=fResult*fBasis;
      nPower--;
    }
    return fResult;
  }
  //-------------------------------------------------------------------
  float fPower (float fBasis, int nPower) // Вычисляет любую степень.
  {
    float fResult=1;
    if( nPower==0) fResult=1;
    else if( nPower>0) fResult=fPositivePower(fBasis, nPower);
    else if( nPower<0) fResult=1/(fPositivePower(fBasis, (nPower*-1));
    // Предварительно делаем степень положительной...
    return fResult;
  }
  //-------------------------------------------------------------------
  int main()
  {
    float fBasis, fResult;
    int nPower;
    cout<<endl;
    cout<<"************************************************************"<<endl;
    cout<<"Работает программа вычисления заданной степени
  числа."<<endl;
    cout<<"Введите число - основание степени: ";
    cin>>fBasis;
    cout<<endl;
    cout<<"Введите степень, в которую Вы хотите его возвести: ";
    cin>>nPower;
    cout<<endl;
    fResult=fPower(fBasis, nPower);
    cout<<"Число "<<fBasis<<" в степени "<<nPower<<" равно
  "<<fResult<<"."<<endl;
    cout<<"Нажмите любую клавишу для выхода..."<<endl;
    getch();
    cout<<"************************************************************"<<endl;
    cout<<endl;
    return 0;
  }

Обратите внимание, хороший прием ставить в начале имени переменной букву, обозначающую ее тип, чтобы потом не мучаться: fResult, f - с плавающей запятой, nPower, n - целое, для строки s можно указывать.

Квадратное уравнение, и пример правильного :) оформления.

Оформление формы:

http://russianenterprisesolutions.com/sbo/im/43.jpg

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  int d;
  int a;
  int b;
  int c;
  float x1;
  float x2;
  a = StrToInt(Edit1->Text);
  b = StrToInt(Edit2->Text);
  c = StrToInt(Edit3->Text);
  d=pow(b,2)-(4*a*c);
  Label7->Caption=IntToStr(d);
  if(d<0)
      {Label10->Caption="Корней нет";}
  else
      {x1 = (-b+sqrt(d))/(2*a);
      x2 = (-b-sqrt(d))/(2*a);
      Label8->Caption=FloatToStr(x1);
      Label9->Caption=FloatToStr(x2);}
  }

Наталия

Меняем местами значения двух переменных:

ответ к задаче № 18:
пусть исходные значения такие: x = a, y = b
y := x + y; {после этого x = a, y = a + b}
x := y - x; {x = b, y = a + b}
y := y - x {x = b, y = a}
Марсель

Тоже по 18-му:

Обменять значение двух переменных (18 задача) проще всего конечно так:
y=y-x;
x=y+x;
y=x-y;

Насчёт 17 задачи, в уме всё-таки проще решить.
Варианты:
мы вытаскиваем две белые: их изымаем, в корзину кидаем чёрную;
белая и чёрная: чёрную изымаем, белую обратно в корзину;
две черные: одну изымаем, другую обратно в корзину.
То есть мы никак не сможем изъять одну белую, только две белых сразу, а так как изначально их было нечётное количество: 75 , то по любому одна белая останется и вытащить её никоим образом не получится.
Соответственно последней останется именно белая.
Евгений

Если кому интересно :) вот еще один вариант.

- Рядовой Иванов, выйти из стpоя!
Иванов падает без сознания. Гpохот... Командиp:
- Что с ним?
- Вышел из стpоя...

Задача 18:
обмен значений переменных не успользую третью переменную.
Имееться довольно протстое решение :) (классическое) через операцию исключающее ИЛИ - XOR
давайте вначале немного рассмотрим саму операцию XOR
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
вспомним как данные храняться в памяти ЭВМ (там разный двоичный код и т.д.). Теперь поэтапно рассмотрим наши операции (чтобы многие вопросы отпали сами собой)
допустим :
X=5 = (0b101)-двоичное представление числа :)
Y=2 = (0b010)-для того чтобы мы видели как биты перемещаються
теперь
1 - этап
X=X xor Y (побитная операция исключающего ИЛИ)
в результате имеем следующее
X=7 = (0b111)
Y=2 = (0b010)
2 - этап
Y=Y xor X
в результате имеем следующее
X=7 = (0b111)
Y=2 = (0b101)
3 - этап
X=X xor Y
в результате имеем следующее
X=7 = (0b010)
Y=2 = (0b101)
всё обмен прошёл.
так что имеем следующие операции
x=x xor y
y=y xor x
x=x xor y
вот собственно и всё решение
Art

XOR, вообще полезная операция, во многих алгоритмах логических применяется.

Одна знакомая попросили Альберта Эйнштейна позвонить ей по телефону, но предупредила, что её телефон очень трудно зпомнить: 24361
- И чегo же тут трудного? - удивился Эйнштейн. - Две дюжины и 19 в квадрате.

Кстати, где-то прочитал - как быстро запомнить последовательность: 144121100816449362516941 ? Какая в ней закономерность?

Отец пpовеpяет тетpадкy маленького сына:
- Почемy ты так неpовно пишешь кpючочки?
- Это не кpючочки, папа, это интегpалы.

Из колонки Ломтик с цитатами на Арбузе www.arbuz.uz :
Леспромхоз решил вырубить сосновый лес, но экологи запротестовали. Тогда директор леспромхоза всех успокоил, сказав: "В лесу 99 процентов сосен. Мы будем рубить только сосны. После рубки сосны будут составлять 98 процентов всех деревьев". Какую часть леса вырубит леспромхоз?

Эта задача на сообразительность будет нашим заданием N 26. Решать своим собственным умом эту задачу не надо, а вот процесс вырубки надо смоделировать. Моделируем-моделируем, моделируем-моделируем, моделируем-моделируем (точнее, код пишем, а моделировать компьютер будет конечно), до тех пор пока процент сосен в виртуальном лесу не станет меньше или равным 98%.

Исходно пусть в лесу будет некоторое случайное число деревьев, датчиком случайным воспользуйтесь, и на каждом шаге считайте процент сосен. В одной переменной - общее число дерев, в другой - сосен. Дождались конца цикла, и смотрим, какую часть леса вырубили.

  Полюбуйтесь, какую мощную программу Лена написала, сама выбрала задачу и сделала. Надо
  сказать, что нетривиальные приемы использованы, я лично мыслю
  шаблонно и не додумался бы до таких манипуляций со строками (!).
И по оформлению образцово.

Допустим, что девушка - человек. Так как она девушка, то она молодой человек, а молодой человек есть парень. Но парень - не девушка!
Мы пришли к противоречию, значит исходное предположение неверно, то есть девушка - не человек!

  Преобразование десятичной дроби с периодом в обычную дробь

  var c,d,p,xs:string;
  var i, stv, yv,yu,stu,ip,xv,xu,del,xc,xch, xzn, ost1,ost2:integer;
  var x:real;
  begin
  writeln( ' chislo ' );
  writeln( ' c= ' ); // целая часть десятичной дроби
  readln(c);
  writeln( ' d= ' ); // дробная часть до периода
  readln(d);
   writeln( ' p= ' ); // период
  readln(p);
   
  //Найти количество символов в дробной части - степень 10 для
  вычитаемого
       stv:=length(d);
   
  //Найти количество символов в периоде, для записи числа с
  открытым периодом
      ip:=length(p);
   
  //Найти степень 10 для уменьшаемого
      stu:=stv+ip;
      
   
  //Записать строку десятичной дроби с открытым периодом
      if d= ' ' then xs:=c+ ' , ' +p;
      
       xs:=c+ ' , ' +d+p;
      
  for i:=1 to ip do //открытых периодов должно быть не меньше, чем
  чисел в периоде
           xs:=xs+p;
      
   
  //Преобразовать строку в число
      x:=StrToFloat(xs);
   
  //Найти вычитаемое, целую часть десятичной дроби
  //В степень пришлось циклом возводить. Т.к используя "power"
  получались числа разных типов, и дальше нельзя было к ним
  применить"div и mod", а очень надо было.
      yv:=1;
         if stv=0 then xv:=trunc(x)// если степень равна нулю, то
  вычитаемое равно дроби
         else
         begin
         for i:=1 to stv do yv:=yv*10;
         xv:=trunc(x*yv);
         end;
     
  //Найти уменьшаемое, целую часть десятичной дроби
          yu:=1;
         for i:=1 to stu do yu:=yu*10;
          xu:=trunc(x*yu);
   
  //Найти разность (xu-xv), это будет числитель обычной дроби
      xch:=xu-xv;
   
  //Найти знаменатель обычной дроби
      xzn:=yu-yv;
   
  //Если числитель больше знаменателя, найти целую часть дроби
        if xch>xzn then
         begin
              xc:=xch div xzn;
         
              //Определить новый числитель
             xch:=xch mod xzn;
         end
     else
        xc:=0;
        
  //Сократить дробь:
  // 1. Найти наибольший общий делитель числителя и знаменателя
  //первый делитель равен числителю. делитель уменьшать на один
         del:=xch;
         ost1:=xch mod del;// остаток от деления числителя на делитель
         ost2:=xzn mod del;// ……знаменателя на делитель
   
       while (ost1<>0)or(ost2<>0) do// ТАК И НЕ ПОНЯЛА почему, когда
  «and», не
       begin // правильно?????????????
         del:=del-1;
         ost1:=xch mod del;
         ost2:=xzn mod del;
        end;
   
  //2. Разделить на общий делитель числитель
         xch:=xch div del;
   
  // и знаменатель
         xzn:=xzn div del;
         writeln( ' xzn2= ' ,xzn);
   
  //Десятичная дробь с периодом
       write(c, ' , ' ,d, ' ( ' ,p, ' ) ' , ' eto ' );
   
  //Вывод целой части обычной дроби
        if xc=0 then write( ' ' );
        if xc>0 then write(IntToStr(xc), ' i ' );
   
  //дробная часть обычной дроби
         write(IntToStr(xch), ' / ' ,FloatToStr(xzn));
   
   readln;
   
  end.

Насчет того, что нельзя применить div и mod. Если получено дробное число, тип Real/Double, то его всегда можно округлить с помощью функции round(), которая возвращает целое число (Integer). К нему уже и можно снова див/мод применять.

В стародавние времена, после появления водки в странной посуде по 0,8 л. возникла проблема - как же это на троих-то пить? Математики предложили решение: наливаем по 100г и сводим задачу к классической.


Дэниэл Канеман и его покойный коллега Амос Тверски описали простые остроумные эксперименты, проливающие свет на человеческую неадекватность восприятия. Вот некоторые из них:
ЗАДАЧА ПРО ЛИНДУ
Студентам математического факультета предлагали решить примерно такую задачу:
Линда - зрелая женщина, которой стукнул тридцатник, и энергия из нее так и прет. На досуге она заворачивает красивые тосты не хуже усатых грузинских тостмейкеров и при этом может, не моргнув глазом, опрокинуть стакан самогона. Кроме того, ее бесят любые проявления дискриминации и возбуждают демонстрации в защиту африканских носорогов.
Внимание, вопрос:
Какой из двух вариантов вероятнее: 1 - то, что Линда - кассир в банке или 2 - то, что Линда - кассир в банке и феминистка?

Пауза - думаем.

Свыше 70% участников эксперимента выбирали второй вариант, потому что предварительное описание Линды соответствовало их представлениям о феминистках, хотя это описание не имело отношения к делу и носило отвлекающий характер, как серебристая блесна с незаметным крючком для щуки. Студенты, изучавшие теорию вероятностей, знали, что вероятность наступления простого события выше вероятности наступления составного - то есть, общее количество кассиров больше, чем количество кассиров-феминисток. Но клюнули на блесну и попались на крючок. (Как вы понимаете, правильный ответ - 1).
Отсюда вывод: стереотипы, довлеющие над людьми, легко затмевают трезвый рассудок.
Феликс Кирсанов www.orator.ru

Поставила я на компьютере пишуший CD, а мужу не сказала, что их, сд-ромов, теперь два.
И вот сижу на кухне, пью кофе под сигаретку,
вдруг влетает муж с глазами, полными ужаса и кричит:" Катя, скорей иди сюда. Там что-то случилось. Я положил диск в лоток, а он куда-то пропал."
Прихожу и вижу: действительно пустой лоток. А вы догадались, куда пропал диск?

...

А это наверное не столько про женщину, сколько про блондинку :)

Приходит в казино женщина, играет в рулетку. Ставит фишки на число "22" На это число выпадает выигрыш. Она с невозмутимым видом ставит все выигранные фишки опять на число "22" На что крупье вежливо ей замечает:
- Мадам, вероятность Вашего следующего выигрыша невероятно мала - может все-таки поставите фишки и на другие числа, поверьте моему опыту!
Женщина,улыбаясь отвечает:
- Ничего, у меня своя система игры.
Выигрыш опять выпадает на число "22". Все в изумлении! И так 10 раз подряд - казино разорено!!! К этой женщине в отчаянии подходит директор разорившегося казино:
- Мадам! Мы разорены! Так расскажите, в чем состоит Ваша система?
- Все очень просто!Я приехала в Ваш город 7 числа, поселили меня в комнате под номером 7, приехала я в вагоне под номером 7...
- Ну?! - не понимая восклицает директор.
- Что - ну, трижды семь - двадцать два!!!


(c) 2004 Сергей Бобровский bobrovsky@russianenterprisesolutions.com

Школа программирования с нуля
http://russianenterprisesolutions.com/sbo/

Все предыдущие выпуски базового курса тут:
http://russianenterprisesolutions.com/sbo/base.htm

 

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull
Отписаться

В избранное