Задание на сейчас. найти максимальное вхождение одного слова в другое в СЛОВАРЕ - смотри ниже!!!
Перл - со словарём не справился;
Для C++ . - У меня перебирает весь словарь за 17 секунд;
Для JS - Около минуты. Говорили что Перл старый, ни на что не способный язык. Проверим?(часть 2) (комментарий);
Всё. Пока ничего другого, полностью рабочего нет.
Не нужно писать решение для единичных слов. Нужно - решение для словаря.
Возьмём список русских существительных, например отсюда: https://github.com/Harrix/Russian-Nouns/releases/download/v2.0/russian_nouns_v2.0.zip
Нужно найти максимальное вхождение одного слова в другое. Полные вхождения слов - не допускаются - это вроде было ясно и понятно всем. — Это задание. Это!!!
Самое простое и наглядное решение в составлении слов это:
/(\w+) \1/
Так-как даже я уже ничего не могу найти в первой части:
Говорили что Перл старый, ни на что не способный язык. Проверим?
Предлагаю собрать сюда наиболее значимые решения из 1 части.
Итак:
В начале, мы просто делали из
шлакоблок + окунь = шлакоблокунь
На разных языках. Там есть решения. Затем все стали зачем то уменьшать количество строк и символов - победил Перл - но это вообще не интересно.
Теперь, самое главное:
Говорили что Перл старый, ни на что не способный язык. Проверим?
Здесь все согласились что Перл хороший и годный язык, но С++ всё равно быстрее. В связи с этим, было предложено:
Говорили что Перл старый, ни на что не способный язык. Проверим?
Возьмём список русских существительных, например отсюда: https://github.com/Harrix/Russian-Nouns/releases/download/v2.0/russian_nouns_v2.0.zip На основе этого списка создадим новый, со всеми новыми сочетаниями, где перекрываются не менее 3 букв. Тут даже секундомером можно замерять. У меня на моем стареньком ноуте ушло несколько минут и сгенерировалось почти 40 Мбайт из одного. У Вас есть код на Перле и C++. Можете сравнить время. Так как здесь тоже работа со строками, то у Перла есть шанс.
Но потом договорились до изменения задания:
Тут ведь уже говорили - что основное время программы - это ввод и вывод. То есть в задании нужно сделать как можно меньше выводов.
Единственное что мне приходит в голову - найти максимальное вхождение одного слова в другое. —!!! Это и стало основным и новым заданием. !!!—
Эти все задачи были решены для Перл и С++
Для Перл. 3 варианта решения. Но ни одно не берёт весь словарь:
#!/usr/bin/perl
use utf8;
use open qw(:std :utf8);
$t = time();
$| = 1;
open D, 'russian_nouns.txt';
for(0..3000) {
$vv=<D>;
$vv =~ s/\s+$//;
@d = (@d, $vv);
}
close D;
@d2 = @d;
for $v (@d){
++$ii; if (++$j>99){
$t2 = time()-$t;
print $ii." прошло $t2 секунд. $sov1 $str\n"; $j=0;}
for $v2 (@d2) {&resh3 ()}
M1:
}
sub resh3 {
$lv = length $v;
$lv2 = length $v2;
if($lv>$lv2) {
for($i=$lv2; $i>1; $i--) {
$c = substr ($v, -$i,);
$c2 = substr ($v2, 0, $i);
if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
$sov = length $c;
if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
}
}
}
else {
for($i=$lv; $i>1; $i--) {
$c = substr ($v2, -$i,);
$c2 = substr ($v, 0, $i);
if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
$sov = length $c;
if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
}
}
}
}
sub resh1 {
$r=''; $l='';
for(split(//,$v2)){
$r .= $_;
if ($v =~ /$r$/) {$l=$r}
}
#print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
if ($l and ($l ne $v2) and ($l ne $v)){
$sov = length $l;
if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}
sub resh2 {
if($v ne $v2) {
$_ = "$v $v2";
/([^ ]*?)([^ ]*) \2/;
if ($2 and ($2 ne $v2) and ($2 ne $v)){
$sov = length $2;
if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}
}
}}
Для C++ . У меня перебирает весь словарь за 17 секунд.:
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;
void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
len = 0;
for(auto &ch: s1)
{
if(len == s2.size())
{
break;
}
if(ch == s2.at(len))
{
len += 1;
}
else
{
len = 0;
}
}
if(!len)
{
res = "";
}
else
{
string s3 {s2};
s3.erase(0, len);
res = s1;
res += s3;
}
}
void getlines(vector<string> &lines, fstream & f)
{
string str;
while(getline(f, str))
{
lines.push_back(str);
}
}
int main()
{
fstream inFile;
inFile.open ("russian_nouns.txt", std::fstream::in);
vector<string> lines;
getlines(lines, inFile);
size_t maxLen {0};
size_t rusMaxLen {0};
string maxRes {""};
time_t startTime = time(nullptr);
size_t counter {0};
for(auto &s1: lines)
{
for(auto &s2: lines)
{
counter += 1;
if(s1 == s2)
{
continue;
}
if(s1.size() < maxLen)
{
continue;
}
if(s2.size() < maxLen)
{
continue;
}
size_t len {0};
string res;
check_combine(res, len, s1, s2);
if(res == s1)
{
continue;
}
if(res == s2)
{
continue;
}
if(len > maxLen)
{
maxLen = len;
rusMaxLen = maxLen / 2;
time_t delta = time(nullptr) - startTime;
string deltaStr {s2};
deltaStr.erase(len);
maxRes = deltaStr + " - " + s1 + '-' + s2;
cout << counter << "\t прошло: " << delta << " секунд, длина: ";
cout << rusMaxLen << ", " << maxRes << '\n';
}
}
}
cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
time_t delta = time(nullptr) - startTime;
cout << "Полное время переборов: " << delta;
inFile.close();
return 0;
}
Ниже - не решения текущей задачи! Не решения. Ниже - просто выборка всех решений, на всех языках с прежней темы.
Блин. Как же сложно с людьми с недостаточным образованием. Я вот уже 6 раз написал - и всё равно будут писать про Шлокоблококунь.
php:
➜ php i.php "папа + папаха"
папаха% ➜ php i.php "шлакоблок + окунь"
шлакоблокунь%
➜ cat i.php
<?php
for ($i = 1; $i <= mb_strlen(trim(explode('+', $argv[1])[0])) && $i <= mb_strlen(trim(explode('+',$argv[1])[1])); $i++)
if (mb_substr(trim(explode('+', $argv[1])[0]), mb_strlen(trim(explode('+',$argv[1])[0])) - $i) === mb_substr(trim(explode('+',$argv[1])[1]), 0, $i))
$j = $i;
echo (isset($j)) ? trim(explode('+',$argv[1])[0]). mb_substr(trim(explode('+',$argv[1])[1]), $j) : 'error';
Говорили что Перл старый, ни на что не способный язык. Проверим? (комментарий)