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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> сравнение 2 массивов, сравнить элементы массива с многомерным 
:(
    Опции темы
alyam
Дата 9.8.2007, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



ребят, подскажите как сделать вот такую вещь:
допустим есть файл, в котором встречаются строки
...получено от Климбовского Олега.
...получено от Климбовского Валерия.
...получено от Багаповой Елены.

есть многомерный массив 
@fio=([Климбовский,Олег],[Багапова,Елена])

произвожу поиск по шаблону и получаю массив:
/^(.*?) получено от (.*?)\.$/
@getfio=split(/ /,$2)
т.е. @getfio=[Климбовского,Олега]

а как потом сравнить массивы @fio и @getfio (проклятые падежи smile ), если совпадает фамилия и имя, то мне нужно произвести необходимые действия.



Это сообщение отредактировал(а) alyam - 9.8.2007, 12:49
PM MAIL   Вверх
Nab
Дата 9.8.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

foreach(@fio){
   print "Нашли" if $_->[0] eq $getfio[0] and $_->[1] eq $getfio[1]
}



--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
alyam
Дата 9.8.2007, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



разве "климбовский" будет совпадать с "климбовского". если только обрезать несколько последних символов у элементов @getfio, а полученный результат потом искать в массиве @fio

и еще в @getfio может быть не два элемента а один [климбовского] или даже 3 [климбовского,олега,владимировича]. как сделать код Nab, более универсальным?

Это сообщение отредактировал(а) alyam - 9.8.2007, 14:19
PM MAIL   Вверх
Nab
Дата 9.8.2007, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



хех, это задача совсем другого плана, думаю надо поискать модули для работы с русской морфологией, по поводу двух, или трех то вот так:

Код

sub similar {
  # это функция похожести, как вы ее реализуете решайте сами, 
  # тут на форуме лингвисты у нас были, помниться задачку сложную одну решали :)
}

foreach(@fio){
   last if similar($_->[0], $getfio[0]) 
             and ((not $getfio[1] or similar($_->[1], $getfio[1]))
                      and (not $getfio[2] or similar($_->[2], $getfio[2])))
}

print $_->[0]


здесь учитываеться сначала фамилия потом имя если оно есть и потом отчество... 
можно сделать еще сложнее и учитывать наличие этих компонетов и в массиве записей.


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
alyam
Дата 9.8.2007, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



это сложно сделать? помоги, пожалуйста
PM MAIL   Вверх
Nab
Дата 9.8.2007, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Для меня этот вопрос сейчас слишком тяжел, катастрофически не хватает времени... так что извини smile


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
alyam
Дата 9.8.2007, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



я имел ввиду 
можно сделать еще сложнее и учитывать наличие этих компонетов и в массиве записей. 

с переводом винительного падежа в именительный я разберусь как нибудь...
PM MAIL   Вверх
vadiml
Дата 9.8.2007, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

потом @fio превратить в тоже в хеш и тогда ни чего не придется искать, только проверять вхожение в него

Добавлено через 6 минут и 3 секунды
или еще вариант -- создать хеш, в котором все окончания будут срезаны и проверять пришедшие фамилии на частичное совпадение, правда тут тогда существует небольшая вероятность совпадения фамилий

ЗЫ  я когда-то считал слова в книге для получения оценки гнездового гнездового входжения (т.е. однокоренных слов), приходилось учитывать все варианты, т.е. не только существительные -- если открыть правила, то вариантов оказывается совсем не много
PM MAIL Jabber   Вверх
alyam
Дата 10.8.2007, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



я сделал так.
преобразовал двумерный массив в одномерный. у именительных падежей убрал 2 буквы в окончании, у винительных падежей убрал 3 слова в окончании.
получилось @fio=("Климбовск Ол", "Климбовск Валер", "Багапо Еле")
@getfio=("Климбовск Ол")

в моем случае работает, а на универсализм я не претендую.

Это сообщение отредактировал(а) alyam - 10.8.2007, 09:20
PM MAIL   Вверх
vadiml
Дата 10.8.2007, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



если @fio пребразовать в хеш
%fio = ("Климбовск Ол" => 1, "Климбовск Валер" => 1, "Багапо Еле" => 1) поиск будет гораздо быстрее, т.к. в хеш уже заложен поиск, а массив надо перебирать
Проверять можно так:
if ( $fio{$getfio} ) {
# автор письма найден
}
else {
# новый автор
}
В хеше можно хранить не "1", а указатель что с письмом делать, главное чтоб значение не возвращало false
PM MAIL Jabber   Вверх
alyam
Дата 11.8.2007, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



не. хеши не подойдут... мой вариант тоже не подошел. некорректно работает с женскими фамилиями и именами.
вернулся к варианту с многомерными массивами.
подскажите такую вещь:
есть массив многомерный @fio=([Климбовский,Олег],[Багапова,Елена])
мне нужно одну из этих строчек объединить через точку.
т.е. климбовский.олег или багапова.елена
как это можно сделать попроще? функцию join не соображу как использовать в этом случае?


Это сообщение отредактировал(а) alyam - 11.8.2007, 21:32
PM MAIL   Вверх
nitr
Дата 12.8.2007, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

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



alyam, вообще-то лучше в ковычки заключать фамилию и имя, да вообще всегда! smile меньше ошибок будет ;)

Код

#!/usr/bin/perl
use strict; use warnings;

my @fio = (['Климбовский','Олег'], ['Багапова','Елена']);
print join('.', @{$fio[0]});



--------------------
PM   Вверх
fray
Дата 12.8.2007, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



думаю здесь нужно провети типизацию фамилий в русском языке, то есть есть фамилии которые скланяются, а есть которые нет, можно воспользоватся учебником русского язывака, выбрать там все окончания которые образуются, при склонении, определять род (жен/муж), резать окончания, и сравнивать.., думаю, что сам процесс сравнения строк в перле, объяснять не столь важно smile.(Количество фамилий - не бескончно, максимум что-то около 150 милн. smile, облегчает задечу что большинсво фамилий заканчиваются на "ов/ова")
Код

$$fio{'Климбовск Ол'} eq 'Климбовский Олег' || 'Климбовская Оля' :)))


Это сообщение отредактировал(а) fray - 12.8.2007, 12:27
PM MAIL   Вверх
nitr
Дата 12.8.2007, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

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



fray, 
alyam,
прочтите совет Nab'а smile Да и думаю эту задачу надо решать немного иначе smile Проектирование и т.п., а потом программирование ;)


--------------------
PM   Вверх
amg
Дата 14.8.2007, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



alyam, на CPAN есть модуль Lingua::RU::Sklon, который умеет склонять русские слова. Этот модуль очень сырой, но кое-как работает. С его помощью твоя задача становится элементарной.
Код

use strict;
use Lingua::RU::Sklon;
use POSIX qw(locale_h);
use locale;
setlocale(LC_CTYPE, "ru_RU.cp1251"); 

my @sender = (
'Письмо 1 получено от Климбовского Олега.',
'Письмо 2 получено от Климбовского Валерия.',
'Письмо 3 получено от Багаповой Елены.',
);

my @fio=(['Климбовский','Олег'],['Багапова','Елена']);

SENDER:
foreach (@sender) { # Заменить на построчное чтение из файла, если нужно
  my ($letter,$sender) = m/^(.+?) получено от (.+?)\.$/ or next;
  foreach my $fio (@fio) {
    # В функциях parse_lastname и parse_n двойка означает родительный падеж
    my $fio_rod = ucfirst(parse_lastname($fio->[0],2)).' '.ucfirst(parse_n($fio->[1],2));
    if ($fio_rod eq $sender) {
      print "$letter: отправитель @$fio\n";
      next SENDER;
    }
  }
  print "$letter от $sender: у нас такого нет\n";
}
Лучше даже немного иначе: сначала весь массив @fio перегнать хэш, как советовал vadiml, но с преобразованием в нужный падеж, и тогда будет совсем легко и быстро.
Код

...
my @fio=(['Климбовский','Олег'],['Багапова','Елена']);
my %fio_rod;
foreach my $f (@fio) {
  my $f_rod = ucfirst(parse_lastname($f->[0],2)).' '.ucfirst(parse_n($f->[1],2));
  $fio_rod{$f_rod} = "@$f";
}

foreach (@sender) {
  my ($letter,$sender) = m/^(.+?) получено от (.+?)\.$/ or next;
  if (exists $fio_rod{$sender}) {
    print "$letter: отправитель $fio_rod{$sender}\n";
  } else {
    print "$letter от $sender: у нас такого нет\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.0607 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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