Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Узнать принадлежность числа к одному из диапазонов, и записать в соответствующий файл 
:(
    Опции темы
Suppir
Дата 9.1.2011, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Есть переменная $range, которая задает диапазоны чисел:


$range =

"
1 - 100 = 1.txt
500 - 1000 = 2.txt
1200 - 1500 = 2.txt
6000 - 7000 = 3.txt
6500 - 8000 = 4.txt
12000 - 15000 = 5.txt
"


Далее в программе запускается цикл:

for (1 .. 10000){
    # Необходимо узнать, к какому диапазону принадлежит число, и записать его в соответствующий файл. 
    # если число не принадлежит ни к одному из диапазонов, то сделать next;
    # если число принадлежит сразу к нескольким диапазонам, то записать в соответствующие файлы.
    # если есть диапазон (5.txt), числа из которого ни разу не встречались, то файл 5.txt. создавать не нужно.
}





Это сообщение отредактировал(а) Suppir - 9.1.2011, 19:58
PM MAIL   Вверх
Suppir
Дата 9.1.2011, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Вот что у меня получилось. Диапазон определяется нормально, но не получается записать число в соответствующий файл :(


Код

$range =

"1 - 100 = 1.txt
500 - 1000 = 2.txt
1200 - 1500 = 2.txt
6000 - 7000 = 3.txt
6500 - 8000 = 4.txt
12000 - 15000 = 5.txt"

;

@ranges = split '\n', $range;

foreach $x (@ranges){
    if ($x=~ /\s*(\d+).+?(\d+)\s*=\s*(.+)/){
        $c++;
        $ranges{$c}{min}=$1;
        $ranges{$c}{max}=$2;
        $ranges{$c}{belongs}=$3;
    }
}


for (1 .. 10000){
    print "$_ - ".check_range($_)."\n"
    #как сделать так, чтобы число печаталось не в консоли, а в соответствующий файл?
}



sub check_range{
    local $x = $_[0];
    foreach $c(keys %ranges){
        if ($x >= $ranges{$c}{min} && $x <= $ranges{$c}{max}){
            return ($ranges{$c}{belongs})
        }
    }
    return 0
}

PM MAIL   Вверх
arto
Дата 9.1.2011, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perl -lne 'push @a,[ split "\\s+[-=]\\s+" ]; END { foreach (1..10000) { foreach $a (@a) { if ($_ >= $a->[0] && $_ <= $a->[1])  { print "echo $_ >> $a->[2]" } } } }' | sh
PM MAIL ICQ   Вверх
Suppir
Дата 9.1.2011, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Не совсем понятно, как записать числа в нужный файл. 
Дело в том, что у меня не однострочник, и эта конструкция записи в файл не подойдет...
А можно на примере моего кода - как записать результат в нужный файл?



Это сообщение отредактировал(а) Suppir - 9.1.2011, 21:45
PM MAIL   Вверх
Suppir
Дата 9.1.2011, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Все, получилось:

Код

$range =

"1 - 100 = 1.txt
500 - 1000 = 2.txt
1200 - 1500 = 2.txt
6000 - 7000 = 3.txt
6500 - 8000 = 4.txt
12000 - 15000 = 5.txt"

;

@ranges = split '\n', $range;

foreach $x (@ranges){
    if ($x=~ /\s*(\d+).+?(\d+)\s*=\s*(.+)/){
        push @range, [$1, $2, $3];
        local $file = $3;
        open($file, ">$3");
    }
}


for (1 .. 10000){
    local $file = check_range($_);
    next if $file == 0;
    print $file "$_\n";
}


sub check_range{
    foreach $a (@range){
        if ($_ >= $a->[0] && $_ <= $a->[1]){return $a->[2]}
    }
    return 0
}

foreach $a(@range){
    local $file = $a->[2];
    close $file;
    if (-s $file == 0){unlink $file}
}




Если кто знает, как подсократить код и улучшить, буду благодарен!



Это сообщение отредактировал(а) Suppir - 9.1.2011, 22:11
PM MAIL   Вверх
arto
Дата 9.1.2011, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perl -lne 'push @a,[ split "\\s+[-=]\\s+" ]; END { foreach (1..10000) { foreach $a (@a) { if ($_ >= $a->[0] && $_ <= $a->[1])  { print { unless (ref \$a->[2] eq "GLOB") { open $a->[2],">",$a->[2] }; $a->[2]} $_ } } } }'

PM MAIL ICQ   Вверх
Suppir
Дата 11.1.2011, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Спасибо. Нашел в своем коде ошибку:

вместо проверки:
Код

    local $file = check_range($_);
    next if $file == 0;



нужно было писать:

Код

if ($file = check_range($_)){

 }



Это сообщение отредактировал(а) Suppir - 11.1.2011, 12:57
PM MAIL   Вверх
alezzz
Дата 11.1.2011, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



Тут мне не совсем понятно:
Код

push @range, [$1, $2, $3];
local $file = $3;
open($file, ">$3");


Сначала переменной $file присваивается имя файла и переменная используется как скаляр, а затем эта же переменная уже используется как дескриптор файла. Строка local $file = $3 не лишняя?
PM MAIL   Вверх
Suppir
Дата 11.1.2011, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



alezzz, так точно. $file используется и как строка, и как дескриптор файла. Вроде, работает.

Добавлено через 2 минуты и 47 секунд
Цитата(alezzz @  11.1.2011,  14:37 Найти цитируемый пост)
Строка local $file = $3 не лишняя? 


Если написатЬ:

push @range, [$1, $2, $3];
open($3, ">$3");

то работать не будет.


А если написать:

push @range, [$1, $2, $3];
local $file = $3;
open($file, ">$3");

то работает.


Вообще, очень многие функции не работают с переменными вроде $1, $2, $& и т.п. Приходится присваивать их значение временным переменным.

Это сообщение отредактировал(а) Suppir - 11.1.2011, 20:33
PM MAIL   Вверх
alezzz
Дата 11.1.2011, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



Да, действительно не лишняя smile . Почитал внимательно описание open, понял о чем речь.
PM MAIL   Вверх
alezzz
Дата 11.1.2011, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



а если подсократить код, то осмелюсь предложить без функции:
Код

for (1 .. 10000){
     foreach $a (@range){
        if ($_ >= $a->[0] && $_ <= $a->[1]){
          print {$a->[2]} "$_\n";
        }
    }
}

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0635 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.