Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Освой Самостоятельно Perl за 24 часа


Автор: Lisssa 1.10.2011, 15:17
В ходе самообучения по книге "Освой Самостоятельно Perl за 24 часа" возникают вопросы , на которые хотелось бы найти ответы. Некоторые моменты ну никак не вяжутся с моей логикой. smile 

Буду вносить все вопросы , которые появятся в ходе обучения в эту тему.
Всем спасибо за внимание. smile 


Автор: Lisssa 2.10.2011, 13:04
На третьем занятии : ,есть игра “Угадайка”.
Вот пример скрипта –
Код

#!/usr/bin/perl -w
print "\n\r\r\Угадайте число от 0 до 9:\n Введите задуманное значение\n\r\r\r\r";
chomp($a=<STDIN>);
$b=int(rand(10));
if ($a < $b) { print "Недобор!\n"; }
elsif ($a > $b) { print "Перебор!\n"; }
еlse { print "Вы угадали!\n"; }


 В ней задействованы некоторые именованные  унарные операторы. 
А именно “int” – Возвращает целую часть аргумента “rand”
“rand” – тоже именованный унарный оператор, по определению он: Возвращает случайное число в диапазоне от 0 до указанного в аргументе; если аргумент отсутствует— возвращается случайное число в диапазоне от 0 до 1.
С оператором int все понятно.
Вопрос :
По определению rand должен вернуть число от  0 до 10.(Не обязательно целое, поэтому используется int.), но почему в функции print, сказано , что от 0 до 9 ?
 Где истина ?

Автор: Pfailed 2.10.2011, 13:13
perldoc -f rand
Цитата

rand  EXPR  Returns a random fractional number greater than or equal to 0 and less than the value of EXPR

Говоря по-русски, возвращает число в диапазоне [0, EXPR)

Автор: myth777 3.10.2011, 15:28
Цитата(Lisssa @ 2.10.2011,  13:04)
но почему в функции print, сказано , что от 0 до 9 ?

потому что rand работает от нуля до N.

Автор: shamber 3.10.2011, 21:29
Цитата(myth777 @  3.10.2011,  15:28 Найти цитируемый пост)
потому что rand работает от нуля до N.

не просто до N, а до N не включая N. О чем собственно и говорит круглая скобка в сообщении Pfailed

Автор: Lisssa 6.10.2011, 03:33
  Спасибки огромное , за подсказку.
Вытекает вопрос: 
Как сделать , чтобы включало заданное число ?
Возможно это не возможно.
Попробывала поставить квадратную скобку, выдает вообще хаотичное число.

Код

#!/usr/bin/perl -w
a$ =rand [10];
print  $a;


Автор: Pfailed 6.10.2011, 05:43
Цитата(Lisssa @  6.10.2011,  03:33 Найти цитируемый пост)
Как сделать , чтобы включало заданное число ?

Прибавить 1. Если хотите от 0 до 10 включительно, то int(rand(11))

Автор: myth777 6.10.2011, 13:03
Цитата(Pfailed @ 6.10.2011,  05:43)
Цитата(Lisssa @  6.10.2011,  03:33 Найти цитируемый пост)
Как сделать , чтобы включало заданное число ?

Прибавить 1. Если хотите от 0 до 10 включительно, то int(rand(11))

А если хотите от 1 до 10 то это будет rand(10)+1

Автор: Lisssa 7.10.2011, 02:20
 Спасибки за участие.
Блин немного не корректно задала вопрос. Существует ли способ - это реализовать по синтаксису языка,  чтобы сразу включить 10, а не с помощью математических, арифметических приемчиков ? ))) (Тоесть написать в операторе только 10)

Автор: dixoNICH 7.10.2011, 05:04
можете написать свой перл.

Автор: Lisssa 7.10.2011, 08:30
Ха ну, очень смешно.
 Я то по правде этот еле понимаю, мысли заплетаются, а Вы мне свой предлагаете.
Вот я и спрашиваю может в этом уже такой оператор есть ?  smile 
 Просто , если нет , то на нет и суда нет. Иду дальше продолжать учить , чтобы не заострать внимание на моментах , которые в пустую отнимают время.

Автор: arto 7.10.2011, 08:38
а какие-либо рациональные причины есть для изменения существующего поведения?

Автор: Lisssa 19.10.2011, 00:30
 Извенияюсь за столь не скорый ответ, не было возможности отписать.
  Просто очень похож на математическую науку.
  Соответственно возникает внутренее желание , что бы по всем параметрам был максимально преближен к ней , да бы проще было запомнить.
Нет , я просто пока учу его таким , какой он есть, вот и спросила , есть или нет такая возможность.

Автор: Lisssa 19.10.2011, 01:25
На терьем занятии вконце есть программа, по нахождению простых чисел.
 К сожалению мое учебное пособие в отсканированном виде ужастного качества с кучей ошибок. 
Саму программу я исправить , исправила. Просто увидев написала правильно по памяти.

Код

#!/usr/bin/perl -w
$maxprimes=20;    # Максимально кол. целых чисел
$value=1;            # Значение проверяемое на простое число
$count=0;        # Счетчик найденых чисел
while($count < $maxprimes) {    # Цикл выполняется пока не будет найдено 
                        # заданное кол. простых чисел.
    $value++;            # Инкримент , начинаем с 2.
    $composite=0;        # Флажок в цикле for, обозначает , что в 
                # текущей интерации иследуемое число не 
                # является простым.
    OUTER: for($i=2; $i<$value; $i++) {    # Перебираем все возможные 
                    # множетели числа $value. 
                    # Присваиевается флаг $composite
                    # и программа выходит из обоих 
                    # циклов.
        for($j=$i; $j<$value; $j++) {
            if (($j*$i)==$value) {
                $composite=1;
                last OUTER;
            }
        }
    }
    if (!$composite) {    # Проверяем значение флага, если множители найдены не 
            # были, то флагу присваивается значение 0 и 
            # выполняется данный условный оператор if.
     $count++;
        print "Число $value простое\n";
    }
}


 Есть в конце главы логичное задание, избавится в расчетном цикле от четных значений, чтобы разгрузить программу.
Понятно , что в самой переменной $value избавляемся от четных вариантов. Это легко.
меняем 
Код

$value++;
  на
Код
$value+=2; # Тоесть начиная от 1 прибавляем по 2, тем самым всегда попадая на нечетное число.
 

Так же логично избавиться от четных множителей, но тут уже в тупике  smile 
Блин какие только варианты не пробывала , но в итоге выводит все не то... печатет уже не простые числа, а даже четные.
Вот примеры , которые крутились в голове: (Измененый фрагмент скрипта между меткой OUTER)

Код

OUTER: for ($a=1;($a+1)<$value;$a+=2) {
       next if $a==1;
        for ($b=$a;($b+1)<$value;$b+=2) {
       next if $b==1;
#               if ($a%2 and $b%2){# и такой вариант пробывала...
                if (($a*$b)==$value ){
                $flag=1;
                last OUTER;

 
  Блиннн , ну как избавиться от четных множителей ...

Да по поводу 2 - (Это тоже просто число. С изменыной переменной $value+=2 данной цифры там нет)
Решается очено просто , поэтому вностить в код не стала
Код

print "Число 2 простое\n"; # пишем перед циклом while .

 




Автор: Lisssa 19.10.2011, 02:30
 Второе интересное  задание в конце 3 главы - это усовершенствовать игру "Угадайка".
Нужно написать программу так , чтобы можно было играть в нее пока не угадаешь число.
Я написала два работающих варианта. Одинс помощью цикла for , а второй с помощь цикла while.
 Вот пример второго варианта , если кому понадобиться. ))

Код

#!/usr/bin/perl -w
$b=int(rand(10));
print "\n\r\r\Угадайте число от 0 до 9:\n Введите задуманное значение\n\r\r\r\r";
$flag=1;
while ($flag==1) {
chomp($a=<STDIN>);
if ($a < $b) { print "Недобор!\n"; }
elsif ($a > $b) { print "Перебор!\n"; }
elsif ($a = $b) { print "Вы угадали!\n"; $flag=0;}}

 

Автор: vadiml 19.10.2011, 08:22
> К сожалению мое учебное пособие в отсканированном виде ужастного качества с кучей ошибок. 

Вы бы лучше взяли Learning Perl (Изучаем Perl) и CamelBook, они есть в сети на русском в прекрасном качестве, и ссылки на них приводили на этом форуме не раз.

Автор: baldina 19.10.2011, 09:03
Цитата(Lisssa @  19.10.2011,  01:25 Найти цитируемый пост)
Есть в конце главы логичное задание, избавится в расчетном цикле от четных значений, чтобы разгрузить программу.
Понятно , что в самой переменной $value избавляемся от четных вариантов. Это легко.
меняем 
код Perl
1:
$value++;
  на
код Perl
1:
$value+=2; # Тоесть начиная от 1 прибавляем по 2, тем самым всегда попадая на нечетное число.
 
Так же логично избавиться от четных множителей, но тут уже в тупике   


не $value++ на  $value+=2, а $i++ на $i+=2
с множителями тож самое: $j+=2

Цитата(Lisssa @  19.10.2011,  00:30 Найти цитируемый пост)
 Просто очень похож на математическую науку.
  Соответственно возникает внутренее желание , что бы по всем параметрам был максимально преближен к ней , да бы проще было запомнить.

Полагаете, что 1..N более математично чем 0..N-1?

Автор: Lisssa 19.10.2011, 09:56
Цитата(vadiml @ 19.10.2011,  08:22)
>Вы бы лучше взяли Learning Perl (Изучаем Perl) и CamelBook, они есть в сети на русском в прекрасном качестве, и ссылки на них приводили на этом форуме не раз.

 Спасибо огромное за рекомендацию. Обязательно прочитаю, если осилю дорогу по которой уже пошла, а то еще и месяца не прошло изучения Перл, а уже помутнел разум.
 Вы его рекомендуете совсем очернить ?))) 
   В данное руководстве, я уже 4 главу читаю "списки, массивы.", очень жалко бросать ... Знаете ли не так уж легко эти главы дались.
 Это же хорошо , что ошибки в книге. Когда их исправляешь начиаешь включать голову  smile 

Автор: Lisssa 19.10.2011, 10:36
Цитата(baldina @ 19.10.2011,  09:03)
не $value++ на  $value+=2, а $i++ на $i+=2
с множителями тож самое: $j+=2

 Не , не , Вы наверно очень бегло пробежали глазами по скрипту и не поняли смысла.

Определение: Простое число - это целое число , которое можно поделить только на само себя и на единицу.
 
 $vlaue - это переменная , которая проверяется на принадлежность к простому числу.
Соответствено , было бы логично не проверять четные числа, поэтому сначало присваиваем ему значение
$value = 1;
Ну а потом идем проверкой по нечетным числам инкриментируя 2-ой.
$value+=2.

Идея:
Соответственно $i и $j это множители $value. Нужо перемножить все возможные варианты от 2 до ($value-1), тоесть 
предположим цифра 7 
Если перемножить всеми возможными парами 2,3,4,5,6 , то 7 ну ни как не получим. Вот и есть смысл простого числа.
предположим цифра 6
Перемножаем 2,3,4,5.  Есть пара множителей , которые равны 6 = 2*3, сответственно число не простое.
 Ну и т.д. в хронологичной последовательности .

По поводу не четных множителей я как раз так и пробывала, но почему-то не работет. Просто во втором примере вместо $i и $j использовала $a и $b.
Переписываю этот кусок с множителями $i и $j.
Код

 OUTER: for ($i=1;($i+1)<$value;$i+=2) {
       next if $i==1;
        for ($j=$i;($j+1)<$value;$j+=2) {
       next if $j==1;
####### if ($i%2 and $j%2){# и такой вариант пробывала...
                if (($i*$j)==$value ){
                $flag=1;
                last OUTER;


 ну соответственно оператор 
next if $i==1;  # Чтобы скрипт не перемножил случайно 1 и само число. Тогда множители в этом куске программы будут всегда и она пропустит и простые числа.

>>Полагаете, что 1..N более математично чем 0..N-1? 
Не то имела ввиду, было бы более логично иметь такой знак в математическом смысле , не просто сторого меньше , а меньше или равно. 
Значит в этом смысле его просто не существует, ну и бог с ним и этого синтаксиса вполне хватает.

Автор: MakTpaxep 19.10.2011, 10:58
Цитата(Lisssa @ 19.10.2011,  02:30)
Второе интересное  задание в конце 3 главы - это усовершенствовать игру "Угадайка".
Нужно написать программу так , чтобы можно было играть в нее пока не угадаешь число.
Я написала два работающих варианта. Одинс помощью цикла for , а второй с помощь цикла while.
 Вот пример второго варианта , если кому понадобиться. ))

Код

#!/usr/bin/perl -w
$b=int(rand(10));
print "\n\r\r\Угадайте число от 0 до 9:\n Введите задуманное значение\n\r\r\r\r";
$flag=1;
while ($flag==1) {
chomp($a=<STDIN>);
if ($a < $b) { print "Недобор!\n"; }
elsif ($a > $b) { print "Перебор!\n"; }
elsif ($a = $b) { print "Вы угадали!\n"; $flag=0;}}

В последнем elsif должно быть $a == $b. У вас работает потому что они уже равны к этому времени, но в будущем избегайте этой новичковой ошибки))

По поводу рандома - привыкайте) По всех языках обращение в первому элеметну массива идёт по нулевому индексу. И это очень естественно)

Автор: arto 19.10.2011, 11:50
# perl -MList::Util=sum -le '@prim = qw( 2 ); $n = $prim[-1]+1; while (@prim < $ARGV[0]) { foreach (@prim) { push @prim, $n unless (sum map { $n%$_ ? 0 : 1 } @prim) } $n+=2 } print "@prim"' 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541

Автор: arto 19.10.2011, 12:11
btw, можно упростить smile

Автор: baldina 19.10.2011, 14:17
Цитата(Lisssa @  19.10.2011,  10:36 Найти цитируемый пост)
 Не , не , Вы наверно очень бегло пробежали глазами по скрипту и не поняли смысла.

да, $value++ я пропустил, замечание снимается

Автор: Lisssa 20.10.2011, 06:59
Цитата(MakTpaxep @ 19.10.2011,  10:58)
 В последнем elsif должно быть $a == $b. У вас работает потому что они уже равны к этому времени, но в будущем избегайте этой новичковой ошибки))

- Семён Семёныч!  Ну что же это Вы  ?
- Ааааахх ! Да , точно .

 Ах ну, да точно , оператор elsif ожидает в условии встретить смысловое значение истина или лож. На самом деле хотела задать через оператор сравнения, а именно равенства "==". Блин, а засунула оператор присваивания "=". 
 Буду бороться с невнимательностью всеми силами, а то именно на этом постоянно и спотыкалась в написании.
Спасибки за исправление. smile 

Автор: Lisssa 20.10.2011, 07:14
Цитата(arto @ 19.10.2011,  11:50)
# perl -MList::Util=sum -le '@prim = qw( 2 ); $n = $prim[-1]+1; while (@prim < $ARGV[0]) { foreach (@prim) { push @prim, $n unless (sum map { $n%$_ ? 0 : 1 } @prim) } $n+=2 } print "@prim"' 100

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

Автор: dixoNICH 20.10.2011, 10:19
зачем доступ к двум машинам для того, чтобы сравнить скорость?

Автор: arto 20.10.2011, 11:02
они побегут наперегонки.

Автор: Lisssa 21.10.2011, 07:37
 Угумс . Причем одна однаядерная с двумя гигами , а вторая четех с 4 гигами. Перловский скрипт на мощную , а скрипт с модулем на слабенькую , потом наоборот. ))) 
 Просто он не видел , как машина вичисляет простые числа . Чем дальше тем медленее, забавно на это смотреть. + Там еще у знакогмого на Си есть код, будет интересно сравнить. Хотя по вычислениям Си наверно победит, я не знаю , вот и проверю.
 Дикс ,а  какими средствами и инструментами , Вы замеряете скорость скриптов ?

Автор: Pfailed 21.10.2011, 08:34
Lisssa, http://search.cpan.org/perldoc?Benchmark

Автор: Lisssa 22.10.2011, 03:55
Цитата(Pfailed @ 21.10.2011,  08:34)
Lisssa, http://search.cpan.org/perldoc?Benchmark

 Мдааа , смотрю в книгу , вижу фигу ... smile 

Автор: Lisssa 22.10.2011, 04:21
Цитата(arto @ 20.10.2011,  11:02)
они побегут наперегонки.

 Не получилось запустить твой скрипт (((.

  Запустили прогу на Си и на Perl данный скрипт 
Код

#!/usr/bin/perl -w
$maxprimes=100000;
$value=1;
$count=0;
print "Число 2 простое.\n";
while ( $count < $maxprimes ) {
$value+=2;
$flag=0;
OUTER: for ($a=1;$a<($value-2);$a+=2) {
    next if $a==1;
    for ($b=$a;$b<($value-2);$b+=2) {
    next if $b==1;
        if (($a*$b)==$value ){
        $flag=1;
        last OUTER;
}
    }
        } 
 if (!$flag ) {
$count++;
print "Число $value простое.\n";}}

 Все таки он заработал, я избавилась от четных множителей. Старый скрипт, который не работал (с исключенными четными множетелями) не нашла, видемо потерла. Так что не понятно, почему считал не правильно и выводились четные числа.
Си по скорости победил данный скрипт.

Арто, винды к сожалению у меня нет, чтобы проверить ... (((, да как-то мне страшно пробывать запускать перл там. Мне кажется там жутко неудобно и не понятно , ведь виндоус имеет закрытый код.
 Вот , что получилось у меня:
 
lisssa@orion:/data/school/lesson03>./0320.pl 
Unquoted string "sum" may clash with future reserved word at ./0320.pl line 2.
Number found where operator expected at ./0320.pl line 4, near ": 1 } @prim) } $n+=2 } print "@prim"' 100"
  (Might be a runaway multi-line '' string starting on line 2)
    (Missing operator before  100?)
syntax error at ./0320.pl line 2, near "-le"
Execution of ./0320.pl aborted due to compilation errors.

Вот сам скрипт
Код

#!/usr/bin/perl -w
List::Util=sum -le '@prim = qw( 2 ); $n = $prim[-1]+1; while (@prim < 
$ARGV[0]) { foreach (@prim) { push @prim, $n unless (sum map { $n%$_ ? 0 
: 1 } @prim) } $n+=2 } print "@prim"' 100


Автор: dixoNICH 22.10.2011, 16:44
вы как его запускали? то, что arto написал, засунули в файл и пытались запустить?

Автор: Lisssa 23.10.2011, 01:12
Цитата(dixoNICH @ 22.10.2011,  16:44)
вы как его запускали? то, что arto написал, засунули в файл и пытались запустить?

1)cpan>install List::Util
2) скопировала в файл(исправив шапку под юникс), как обычно chmod +x file.pl
3)./file.pl

Автор: Pfailed 23.10.2011, 08:26
Lisssa, это неверно. Вам нужно прочитать http://perldoc.perl.org/perlrun.html

Например 
perl -MList::Util=sum -e 'print sum(1,2,3)'

это

Код

#!/usr/bin/perl
use List::Util 'sum';
print sum(1,2,3);


Автор: Lisssa 23.10.2011, 09:29
 Спасиба за наводку.  smile 
Блин , многие ссылаются на англоязычную информацию. Если бы действительно владела английским, а не просто переводила слова , то тут бы просто даже не появилась, это же логично, как два плюс два.
 Я и так сейчас "курю"  мануалы на родном языке , а Вы предлогаете еще усугубить енто дело .  smile 
 Может , где нить есть русскоязычный ресурс ?

Автор: Pfailed 23.10.2011, 11:52
Некоторая часть документации переведена на http://perl5doc.ru/

Автор: Lisssa 24.10.2011, 04:40
Спасибки за ресурс.
 Только не могу найти, то что мне надо . Что только не набирала в поиске... Пробовала и преобразовать из Windows в Unix и "конвертирование" , "формат" и т.п.
Подскажите русскую терминологию по данному вопросу, чтобы я могла перевести скрипт в понятный синтаксис под unix.

Автор: Pfailed 24.10.2011, 06:11
Это не из windows в unix, а из однострочного формата в полноценный скрипт.
Опции командной строки описаны в perlrun, там это не переведено.

Автор: Lisssa 24.10.2011, 08:55
 Спасибо , весьма благодарна . smile 
Да в моем пособии по которому сейчас изучаю - это есть в 12 уроке "Работа с командной строки."(потом вернусь)
Запустила оба скрипта. С модулем из командной строки оказался быстрее где-то в 3 раза, чем из учебного пособия , но медленнее Си.
 Сейчас в процессе изучения массивов. Изучение идет туго, думаю напишу не скоро.
Чем дальше, тем труднее  smile
Обратила внимание , что надо обязательно учить терминологию (русскоязычную) и синтаксис, без этого просто не возможно вникнуть с ходу в последующий урок.

Автор: arto 24.10.2011, 09:46
на программу на c можно взглянуть?

Автор: Lisssa 24.10.2011, 11:20
Цитата(arto @ 24.10.2011,  09:46)
на программу на c можно взглянуть?

 Да , конечно. smile 
Она на рабочем компьютере. 
Буду на работе после завтра. Ночью скину.
 Вообще синтаксис Си и PHP c виду, очень похож на Perl. Ну я конечно как новенькая смотрю.  Геометрия похожа .

Автор: Lisssa 26.10.2011, 00:18
Код

#include <iostream>
using namespace std;
int main()

   int x;
   int y;
cout << "1\n";
    for(x=1; x <= 100000; x=x+2)
  {
      for(y=2; y<x; y++)
     {
        if(x%y==0) break;
        if(y==x-1)
      {
         cout << x;
         cout << " \n";
             }
                } 
                  }             
     return 0;          
                   }

Автор: Lisssa 26.10.2011, 09:33
  Переписала код по аналогичной математической схеме , как в примере на Cи

Код

#!/usr/bin/perl -w
$maxprimes=100000;
$value=1;
$count=0;
print "Число 2 простое.\n";
while ( $count < $maxprimes ) {
$value+=2;
$flag=0;
OUTER: for ($a=1;$a<($value-2);$a+=2) {
    next if $a==1;
        if (($value%$a)==0 ){
        $flag=1;
        last OUTER;
}
    }
 if (!$flag ) {
$count++;
print "Число $value простое.\n";}}

 
 Код значительно быстрее вывел результат простых чисел , чем вышестоящие скрипты на Perl, но аказался в раз 5 медленнее Си. 
А ведь у меня была сразу идея написать его в таком виде , не как в учебном пособии. Я побывала построить скрипт с данным оператором "%" )), вот только руки не с того места.
Как сразу в голове просчитать , какой код более быстрый ? По примерному представлению количества операций , который производит код ?

Автор: baldina 26.10.2011, 10:35
Цитата(Lisssa @  26.10.2011,  09:33 Найти цитируемый пост)
Как сразу в голове просчитать , какой код более быстрый ?

хороший вопрос. однозначного ответа нет, потому и говорят, что основанием для оптимизации должно являться профилирование.
однако сравнить два алгоритма можно и нужно (хотя это тоже может оказаться непростой задачей).
обычно анализ основывается на выявлении основной операции (или группы операций) алгоритма и подсчете числа операций в зависимости от размера данных.

в данном случае все довольно просто: в первом алгоритме на один внутренний цикл больше. 
если есть k вложенных циклов, каждый из которых выполняется за n шагов (с точностью до множителя), то класс эффективности алгоритма O(n^k)
таким образом первый алгоритм имеет трудоемкость O(n^3), второй O(n^2), где n это $maxprimes
вот если бы они попадали в один класс эффективности, нам пришлось бы более точный анализ проводить

Добавлено через 1 минуту и 54 секунды
Lisssa, вообще этот вопрос относится к теме "Анализ алгоритмов", который довольно широко освещен в литературе

Автор: Lisssa 4.11.2011, 06:51
Цитата(baldina @ 26.10.2011,  10:35)
Цитата(Lisssa @  26.10.2011,  09:33 Найти цитируемый пост)
Как сразу в голове просчитать , какой код более быстрый ?

потому и говорят, что основанием для оптимизации должно являться профилирование.

таким образом первый алгоритм имеет трудоемкость O(n^3), второй O(n^2), где n это $maxprimes
вот если бы они попадали в один класс эффективности, нам пришлось бы более точный анализ проводить

Добавлено @ 10:37
Lisssa, вообще этот вопрос относится к теме "Анализ алгоритмов", который довольно широко освещен в литературе

 Ясненько, спасибки за ответ. Чуть позже вернусь к профилированию, а пока еще профилоровать то нечем )))
 

Автор: Lisssa 4.11.2011, 07:12
 На четвертом часе идет изучение "Укладка строительных блоков: списки и массивы".
 Как всегда плохо  отсканированный документ дает о себе знать  smile 
 Искала по всему интернету , так и не нашла исправно работающий код программы "Висилица", написанный именно в виде массивов... никто не справился, кто брался.  smile 
 
Вот сам код:
Код

#!/usr/bin/perl -w

@words=qw( Интернет Ответ Принтер Программа ); #Инециализирует список допустимых слов в игре
$guesses[0]="";    # Хранение ранее введеных букв
$wrong=0;    # Колличество неудачных ответов

$choice=$words[rand @words];    # Рандомно выбирается слово из массива @words
$hangman="0-|--<";          # Формируется фигурка    
@letters=split(//, $choice);    # Загаданное слово разбивается на буквы и помещается в массив @letters
@hangman=split(//, $hangman);    # Фигурка разбивается на символы в индексной последовательности и иницализируется в массив @hangman
@blankword=(0) x scalar(@hangman); # @blankword Отображает положение правильно угаданных букв. В начале в @blankword находится список (0) x scalar(@hangman), длинна которого равна колличеству эллементов @hangman. Затем постепенно нули заменяются на угаданные буквы. Это делает далее $blankword[i] = $guess
OUTER:                # Отметка для основного цикла
    while ($wrong<@hangman) {    # Основной цикл выполняется, пока количество неправельных ответов не сравняется с длинной фигурки.
        foreach $i (0..$#letters) {    # Цикл foreach
            if ($blankword[$i]) {    # проверяются эллементы массива @blankword
                print $blankword[$i];    # Все угаданные буквы распечастываются 
            } else {            # , а
                print "-";        # не угаданные заменяются девисами.
            }
        }
        print "\n";
        if ($wrong) {            # Переменная $wrong сожержит количество не правельных ответов.
            print @hangman[0..$wrong-1]    # Если имеется хотябы один не правельный ответ, печатаются $wrong начальных элементов @hangman
        }
        print "\n Ваш выбор: ";        
        chomp($guess=<STDIN>);        # Вводится ответ игрока, функция chomp удаляет завершающий символ новой строки.
        foreach(@guesses) {            # Проверяем - 
            next OUTER if ($_ eq $guess);    # не выводился ли символ ранее. Если да цикл переходит к отметке OUTER и 
        }                    # игрок не наказывается за повторение не правильного ответа.    
        $guesses[$#guesses]=$guess;        # Введена пользователем буква помещается в массив @guesses.
        $right=0;                # Данный флаг указывает на неверные ответы
        for ($i=0; $i<@letters; $i++) {        # В @letters содержащем загаданное слово ищется буква ответа.
            if ($letters[$i] eq $guess) {    # Если буква найдена она
                $blankword[$i]=$guess;        # присваивается соответствующему элементу массива  @blankwords. Все эллементы этого массива это или угаданные буквы или нули.
                $right=1;            # Флаг $right получает значение 1, если хотябы одна буква правильно угадана.
            }
        }
        $wrong++ unless ($right);    # Увеличиваем переменную $wrong при каждом неправильном ответе.
        if (join('', @blankword) eq $choice) {    # Элементы массива @blankwords объединяются в строку, которая сравнивается с исходным словом. Если они совпадут,то
            print "Вы угадали! Загаданное слово было $choice\n"; # это означает , что пользователь угадал слово и распечатается сообщение о победе , после чего 
            exit;    # программа завершится.
        }
    }
    print "$hangman\n Печально, но было загадано слово $choice!\n"; # Основной цикл программа завершается, поскольку игрок исчерпал все свои попытки.




В этой программе продимонстрирован изученый материал 4 часа - списки литералов, массивы, функции split и join, контекст и циклы foreach. Ясно , что программу можно запрограммировать массой различных способов, данная же версия - иллюстрация основных возможностей массивов.

 Данный код программы работает не коректно.
1) Количество дефисов в двое больше , чем количество загадынных букв слова.
2) Ну и из этого логично , не работает часть пограммы , которая бы исправно нашла , что я ввела верную букву.
 Не могу понять , как исправить данную ошибку.  smile 
Help me ! Help me ! ))

Автор: ginnie 4.11.2011, 13:42
Lisssa, как ведет себя программа при использовании английских слов вместо русских?

Автор: arto 4.11.2011, 15:59
# perl -CSA -e '$"="";$n=shift;@a=split"",shift;@c=qw(0)x@a;while(index("@c","0")!=-1){print"@c\n";print"> ";chomp(my$w=<STDIN>);my@b=grep{$b=shift@c;push@c,$_ eq$w&&$b eq"0"?$w:$b;$_}@a;$n-="@a"eq"@b"||0;if($n==0){print"Word was: ";last}@a=@b}print"@a\n"' 6 тест
0000
> t
0000
> т
т00т
> с
т0ст
> е
тест
#

интересно, можно ли короче?

Автор: Lisssa 11.11.2011, 09:54
Цитата(ginnie @ 4.11.2011,  13:42)
Lisssa, как ведет себя программа при использовании английских слов вместо русских?

Спасибки огромное , без этой наводки врядли бы додумалась ...
Изменила 
Код

@words=qw( Интернет Ответ Принтер Программа );

на
Код

@words=qw( Internet Answer Printer Program );


Все действительно заработало. 
И как про это не написали в учебном пособии ?  smile  
Может , кто знает: Как сделать , чтобы русские буквы работали и каким образом проводится диагностика , что трабла именно в языке ?

Добавлено @ 09:56
Цитата(arto @ 4.11.2011,  15:59)
# perl -CSA -e '$"="";$n=shift;@a=split"",shift;@c=qw(0)x@a;while(index("@c","0")!=-1){print"@c\n";print"> ";chomp(my$w=<STDIN>);my@b=grep{$b=shift@c;push@c,$_ eq$w&&$b eq"0"?$w:$b;$_}@a;$n-="@a"eq"@b"||0;if($n==0){print"Word was: ";last}@a=@b}print"@a\n"' 6 тест
0000
> t
0000
> т
т00т
> с
т0ст
> е
тест
#

интересно, можно ли короче?

arto спасибки , вернусь к твоим комментария , как буду изучать 12 урок , работа с командной строки, пока растрачивать себя не могу.

Автор: dixoNICH 11.11.2011, 13:07
подключите use locale, чтобы работатьс русским текстом, должно помочь

Автор: Lisssa 12.11.2011, 01:45
Цитата(dixoNICH @ 11.11.2011,  13:07)
подключите use locale, чтобы работатьс русским текстом, должно помочь

Пробывала добавить:
Код

use locale;

Пробывали и таким методом(Нашла в инете):
Код

use locale;
use POSIX qw (locale_h);
setlocale(LC_CTYPE, 'ru_RU.KOI8-R');

 В cpan предворительно проделала install locale.
Что-то еще нужно сделать ? 

Автор: Lols 12.11.2011, 02:27
Забавно smile А первый вариант можно? Хочу себя проверить.

Автор: Lisssa 12.11.2011, 02:41
Цитата(Lols @ 12.11.2011,  02:27)
Забавно smile А первый вариант можно? Хочу себя проверить.

Немного не поняла, первый вариант чего ? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)