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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Посчитать количество элэментов по двум параметрам, Шаблонный поиск и подсчет 
:(
    Опции темы
makk
  Дата 20.7.2014, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Приветствую всех!

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

Задача следующая, имеется текстовый документ ... в каждой строке записаны данные в формате 

27.06.2014, Data1, Namber, Data2, IDData, Data3

где Data3 имеет всего 4 значения .... Список будет примерно таким .. 

27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3
27.06.2014, Data1, Namber, Data2, IDData, Data3

Важно уточнить ... что ориентация на длинну строки шаблонно сделать нельзя, т.к. некоторые параметры постоянно разные. Все остальные данные меня не интересуют, мне нужно посчитать сколько раз повторяется Data3 из  доступных 4 вариаций ... сложность в том, что поиск я думаю должен быть рекурсивный, по причине того что при сравнении Data3, нужно учитывать состояние Data2 .... Data2 это номера от 1 до 255 ... 

При этом ... если ... Data2 имеет 2 одинаковых значения из 4 ых возможных .. то они не учитываются, а при первом совпадении если имеется строке один из параметров .. происходит переход на следующую строку. Тоесть поиск по двум параметрам в одной строке ... и их подсчет.

Алгоритм на словах такой ... 
Поиск в каждой строке .... условие примерное начало файла данных, Data2 номера как я и сказал, заменил их ..

27.06.2014, Data1, Namber, 1, IDData, Data3_1
27.06.2014, Data1, Namber, 1, IDData, Data3_2
27.06.2014, Data1, Namber, 1, IDData, Data3_1
27.06.2014, Data1, Namber, 2, IDData, Data3_4
27.06.2014, Data1, Namber, 2, IDData, Data3_4
27.06.2014, Data1, Namber, 2, IDData, Data3_4
27.06.2014, Data1, Namber, 2, IDData, Data3_1


Поиск идет конкретного значения например ... только Data3_1 в данных строчках .. таким образом ..

в Data2 берется один ... потом сравнивается ... Data3 ... если параметр Data3_1 найден ... то мы ищем дальше уже не в Data2 равное 1 в данном случае, а переходим до тех пор пока Data2 не станет 2, где цикл поиска вновь начинается сначала ... и после 3 значений Data3_4 найдется Data3_1 и вновь перейдет на Data2 со значением 3 .... 

Как можно это реализовать ?! Помогите пожалуйста! Заранее большое спасибо!

Это сообщение отредактировал(а) makk - 20.7.2014, 12:20
PM MAIL   Вверх
Bulat
Дата 21.7.2014, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



Немного тяжело понять что в конечном счете требуется, но явно нужно копать в сторону регулярных выражений!  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
arto
Дата 21.7.2014, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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

# perl -aF"/,\\s+/" -lne '$h{ join",",@F[1..5] }++; END{ while (($a,$b) = each%h) { print $a, ": ", $b } }'
Data1,Namber,2,IDData,Data3_1: 1
Data1,Namber,1,IDData,Data3_2: 1
Data1,Namber,1,IDData,Data3_1: 2
Data1,Namber,2,IDData,Data3_4: 3

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


Новичок



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

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



Нет смысла использовать регулярки. Если правильно понял, то автору надо это:
Код

my $data3_value = ( split ", ", $line )[5];


Целиком:
Код

#!/usr/bin/perl -w
use strict;
use warnings;
use 5.10.1; # to use say - analog print ... + "\n";

use Data::Dumper;

my $filename = './file_to_test.txt';
# in file filename this:
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 1, IDData, Data3_2
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_1

# read data from file
    open my $fh, "<", $filename or die "Can not open file $filename : '$!'\n";
    my @lines = <$fh>;
    chomp @lines;
    close $fh;

# to count the number of occurrences
    my %counts;
    for my $line (@lines)
    {
        # say $line; # for test
        
        # This is main part of code.
        # Split string by ", " chars and use only 6 element of array (5 if count from 0)
        # if you don`t understand, read google search result:
        # 1. perl срез хеша;  2. perldoc split;
        my $data3_value = ( split ", ", $line )[5];  
        
        # say $data3_value; # for test

        if    ($data3_value eq 'Data3_1') { $counts{'Data3_1'} ++; }
        elsif ($data3_value eq 'Data3_2') { $counts{'Data3_2'} ++; }
        elsif ($data3_value eq 'Data3_3') { $counts{'Data3_3'} ++; }
        elsif ($data3_value eq 'Data3_4') { $counts{'Data3_4'} ++; }
        else                              {    die "error! Data 3 has unknow value!\n"; };
        
    }

# print report:
    # while (($a,$b) = each %counts) { print $a, " count ", $b , " num\n" };
    print Dumper \%counts;

#That is all! ok?


Сработает, если текст разделен жестко по шаблону ", " (запятая + пробел) как у Автора в примере.
То что написал АРТО коротко и работает, но слишком сложно для человека, который не пишет на perl.

Добавлено через 2 минуты и 40 секунд
Вывод:
Цитата

Data3_4 count 3 num
Data3_2 count 1 num
Data3_1 count 3 num


или если через Dumper
Цитата

$VAR1 = {
          'Data3_4' => 3,
          'Data3_2' => 1,
          'Data3_1' => 3
        };


Это сообщение отредактировал(а) DProf - 21.7.2014, 16:41
PM MAIL   Вверх
Bulat
Дата 21.7.2014, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



Цитата(DProf @  21.7.2014,  16:41 Найти цитируемый пост)
Нет смысла использовать регулярки.

Смысл как раз в том, чтобы не плодить кучу кода, а сделать все компактно и понятно, что и сделал arto  smile  


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
DProf
Дата 21.7.2014, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Сразу не заметил, но если надо учитывать data2
Код

my ($data2_value,$data3_value) = ( split ", ", $line )[3,5];


Добавлено через 3 минуты и 21 секунду
Цитата(Bulat @  21.7.2014,  16:55 Найти цитируемый пост)
Смысл как раз в том, чтобы не плодить кучу кода, а сделать все компактно и понятно, что и сделал arto


Ну и попробуйте представить сколько всего надо прочитать человеку, не знающему perl, чтобы понять что в том однострочнике написано. Много кода - не беда, беда когда он непонятный


Это сообщение отредактировал(а) DProf - 21.7.2014, 16:56
PM MAIL   Вверх
makk
  Дата 21.7.2014, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго дня! Спасибо большое за быстрые ответы! Я попытался объяснить проблематику, но наврное слишком перегрузил информацией. 

Даже с этими примерами, я уже могу что-то доделать, я попробую сам довести до ума ... Как было сказано, при поиске к примеру в этом массиве по двум парамертрам результат будет следующий ... 

Где происходит поиск - 

# in file filename this:
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 1, IDData, Data3_2
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_1

Первый запрос на поиск ... ищем ... Data3_1
Выход будет Data3_1 = 2 .... по той причине, что в Data2 где стоят три единицы, это можно сказать еще один ИД номер, где мы считаем всего один раз, при первом совпадении, то есть строка номер 3 уже не будет учитываться, в итоге в следующий строки покажут тоже наличине только одной Data3_1 ... где сумма их будет два.

Пример с поиском Data3_4 .... Выход будет Data3_4 = 1 так как в четырех ИД номера под 2 цифрой их три ... но мы считаем только один раз про ИД .. первые ид номера это 1 1 1 и потом 2 2 2 2  .. в каждом из них только один раз считаем искомую константу. 

Вывод общий должен быть такой .. 

Data3_4 count 1 num
Data3_2 count 1 num
Data3_1 count 2 num

По этой причине нужно учитывать два параметра ... а не только искомую величину .. отсеивая таким образом повторные искомые константы в каждом одинаковом ИД номере. Спасибо вам большое!

Это сообщение отредактировал(а) makk - 21.7.2014, 17:12
PM MAIL   Вверх
Bulat
Дата 21.7.2014, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



Цитата(makk @  21.7.2014,  17:06 Найти цитируемый пост)
Первый запрос на поиск ... ищем ... Data3_1
Выход будет Data3_1 = 2 .... по той причине, что в Data2 где стоят три единицы, это можно сказать еще один ИД номер, где мы считаем всего один раз, при первом совпадении, то есть строка номер 3 уже не будет учитываться, в итоге в следующий строки покажут тоже наличине только одной Data3_1 ... где сумма их будет два.

Пример с поиском Data3_4 .... Выход будет Data3_4 = 1 так как в четырех ИД номера под 2 цифрой их три ... но мы считаем только один раз про ИД .. первые ид номера это 1 1 1 и потом 2 2 2 2  .. в каждом из них только один раз считаем искомую константу. 

Чет все равно не особо понял чего, и где искать, и зачем искать!  smile  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
makk
Дата 21.7.2014, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Посмотрите на результаты поиска которые я привел .. может быть по ним будет ясно, если коротко, это поиск по двум параметрам, где один из параметров имеет только 4 значения и должен быть подсчитан один раз учитывая второй параметр. Считать нужно т.к. таких строчек около 40 000 ... и много файлов с таким же объемом.
PM MAIL   Вверх
Bulat
Дата 21.7.2014, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



makk, у тебя в строке 6 столбцов?? Какие конкретно столбцы нужно учитывать по номерам (если за первый столбец взять тот что слева)??


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
DProf
Дата 22.7.2014, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Какие то странные условия Вы ставите, уважаемый makk.
Но может вот так:
Код

#!/usr/bin/perl -w
use strict;
use warnings;
use 5.10.1; # to use say - analog print ... + "\n";

use Data::Dumper;

my $filename = './file_to_test.txt';
# in file filename this:
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 1, IDData, Data3_2
# 27.06.2014, Data1, Namber, 1, IDData, Data3_1
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_4
# 27.06.2014, Data1, Namber, 2, IDData, Data3_1

# read data from file
    open my $fh, "<", $filename or die "Can not open file $filename : '$!'\n";
    my @lines = <$fh>;
    chomp @lines;
    close $fh;

# to count the number of occurrences
    my %counts;
    my %occurrences;
    for my $line (@lines)
    {
        # say $line; # for test
        
        # This is main part of code.
        # Split string by ", " chars and use only 6 element of array (5 if count from 0)
        # if you don`t understand, read google search result:
        # 1. perl срез хеша;  2. perldoc split;
        # my $data3_value = ( split ", ", $line )[5];
        my ($data2_value,$data3_value) = ( split ", ", $line )[3,5];
        
        # say $data2_value," - ",$data3_value; # for test

        # if    ($data3_value eq 'Data3_1') { $counts{'Data3_1'} ++; }
        # elsif ($data3_value eq 'Data3_2') { $counts{'Data3_2'} ++; }
        # elsif ($data3_value eq 'Data3_3') { $counts{'Data3_3'} ++; }
        # elsif ($data3_value eq 'Data3_4') { $counts{'Data3_4'} ++; }
        # else                              { die "error! Data 3 has unknow value!\n"; };

        # find occurrences
        if    ($data3_value eq 'Data3_1') { $occurrences{'Data3_1'}{$data2_value} = 1; }
        elsif ($data3_value eq 'Data3_2') { $occurrences{'Data3_2'}{$data2_value} = 1; }
        elsif ($data3_value eq 'Data3_3') { $occurrences{'Data3_3'}{$data2_value} = 1; }
        elsif ($data3_value eq 'Data3_4') { $occurrences{'Data3_4'}{$data2_value} = 1; }
        else                              { die "error! Data 3 has unknow value!\n";   };
        
    }

# count the number of occurrences
    for my $data3 (keys %occurrences)
    {
        my %occurrences_data3 = %{ $occurrences{$data3} };
        $counts{$data3} = scalar (keys %occurrences_data3);
    };

# print report:
    while (($a,$b) = each %counts) { print $a, " count ", $b , " num\n" };
    # print Dumper \%counts;

#That is all!


Вывод:
Код

Data3_4 count 1 num
Data3_2 count 1 num
Data3_1 count 2 num


Если все верно, пару слов скажите, где Вы это используете.
PM MAIL   Вверх
Bulat
Дата 22.7.2014, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



Цитата(DProf @  21.7.2014,  16:55 Найти цитируемый пост)
Ну и попробуйте представить сколько всего надо прочитать человеку, не знающему perl, чтобы понять что в том однострочнике написано. Много кода - не беда, беда когда он непонятный


Цитата(DProf @  22.7.2014,  11:44 Найти цитируемый пост)
Какие то странные условия Вы ставите, уважаемый makk.


И сколько раз придется переписывать и перепроверять многострочный скрипт при небольшом изменении условий, тем более человеку не знающему перл, в то время когда несколько строк через регэкспы - нужно патчить всего эти  пару строк.  smile Так что давай оставим выбор конечного варианта на усмотрение автора, без упреков к альтернативным вариантам решения задач.  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
DProf
  Дата 22.7.2014, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Не согласен с Вами, Bulat.
Изменять приведенный скрипт очень легко, ведь сразу понятно где что. Большим он тоже выглядит только потому, что много комментариев. Изменения в соответствии с уточненными условиями я внес очень быстро. А если я неправ, перепишите ка мне однострочник от АРТО с соответстии с условиями автора, чтобы было 
Код

Data3_4 count 1 num
Data3_2 count 1 num
Data3_1 count 2 num


Хотя если на разделе для файла с кодом всего килобайт памяти, то да, это может быть проблемой  smile

Добавлено через 1 минуту и 22 секунды
Цитата(Bulat @  22.7.2014,  13:03 Найти цитируемый пост)
Так что давай оставим выбор конечного варианта на усмотрение автора, без упреков к альтернативным вариантам решения задач

а тут не поспоришь, Вы правы

PM MAIL   Вверх
Bulat
Дата 22.7.2014, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

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



DProf, может уже хватит холивара, прежде чем утверждать что-либо, разумно сначала хотя бы прежде разобраться что требуется, это во-первых! А во-вторых, регулярные выражения присутствуют во многих ЯП, просто в перле их использование упрощено, а вот разбираться с перловым синтаксисом для непосвященного человека, гораздо тяжелее... И Баста!  smile 

Цитата(DProf @  22.7.2014,  13:14 Найти цитируемый пост)
А если я неправ, перепишите ка мне однострочник от АРТО с соответстии с условиями автора, чтобы было 

Вот сначала нужно конкретно понять что требуется, а уже потом доказывать свою правоту!  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
arto
Дата 22.7.2014, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Хотя я не понял условия задачи, но эквивалент представленного скрипта:

# perl -aF"/,\\s+/" -lne '$h{ $F[5] }->{$F[3]}++; END{ while (($a,$b) = each%h) { print $a, ": ", scalar keys $b } }'
Data3_1: 2
Data3_2: 1
Data3_4: 1
#


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


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

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


 




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


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

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