0 / 0 / 1
Регистрация: 24.07.2011
Сообщений: 10
1

Оптимизация работы со строками

30.07.2011, 23:45. Показов 1407. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Снова здравствуйте! В этот раз хотелось бы выслушать предложения по оптимизации алгоритма для определения похожести строк. Данный метод в программе вызывается периодически и примерно 200 млн. раз за каждый обход, время выполнения составляет около 2 минут.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public static bool AreSimilar(string S1, string S2)
{
    if (String.IsNullOrEmpty(S1) || String.IsNullOrEmpty(S2))
        return false;
 
    string S1temp = S1.ToLower(), S2temp = S2.ToLower();
 
    foreach (string s in signore)
    {
        if (((S1temp.Contains(s)) && (!S2temp.Contains(s))) ||
            ((!S1temp.Contains(s)) && (S2temp.Contains(s))))
            return false;
    }
    foreach (string s in repeat)
    {
        if ((S1temp.Contains(s)) && (S2temp.Contains(s)))
            return false;
    }
 
    foreach (string s in sreplace)
    {
        S1temp = S1temp.Replace(s, "");
        S2temp = S2temp.Replace(s, "");
    }
 
    int length1 = S1temp.Length, length2 = S2temp.Length;
    string LastSub = strLongestCommonSubstring(S1temp, S2temp);
    int length = 0;
    do
    {
        length += LastSub.Length;
        S1temp = S1temp.Remove(S1temp.IndexOf(LastSub), LastSub.Length);
        S2temp = S2temp.Remove(S2temp.IndexOf(LastSub), LastSub.Length);
        LastSub = strLongestCommonSubstring(S1temp, S2temp);
        if (LastSub == "")
            LastSub = " ";
    }
    while ((LastSub.Length > 2 + Settings.Strong2) || (char.IsDigit(LastSub[0])));
    int min1 = 4, min2= 4;
    if (length1 < 4)
        min1 = 0;
    else if (length1 < 7)
        min1 = 1;
    else if (length1 < 11)
        min1 = 2;
    else if (length1 < 15)
        min1 = 3;
    if (length2 < 4)
        min2 = 0;
    else if (length2 < 7)
        min2 = 1;
    else if (length2 < 11)
        min2 = 2;
    else if (length2 < 15)
        min2 = 3;
 
    return ((length1 - min1 + Settings.Strong <= length) || (length2 - min2 + Settings.Strong <= length));
}
 
//наибольшая общая подстрока
public static string strLongestCommonSubstring(string str1, string str2)
{
    if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2))
        return "";
 
    string result = "";
    List<int[]> num = new List<int[]>();
    int maxlen = 0;
    for (int i = 0; i < str1.Length; i++)
    {
        num.Add(new int[str2.Length]);
        for (int j = 0; j < str2.Length; j++)
        {
            if (str1[i] != str2[j])
                num[i][j] = 0;
            else
            {
                if ((i == 0) || (j == 0))
                    num[i][j] = 1;
                else
                    num[i][j] = 1 + num[i - 1][j - 1];
                if (num[i][j] > maxlen)
                {
                    maxlen = num[i][j];
                    result = str1.Substring(i - maxlen + 1, maxlen);
                }
            }
            if (i >= 2)
                num[i - 2] = null;
        }
    }
    return result;
}
signore, sreplase, srepeat - массивы строк, их предназначение должно быть понятно. Уже не помню, откуда был позаимствован метод нахождения наибольшей общей подстроки (вроде бы с Википедии), я его немного модифицировал (изначально метод находил лишь длину наибольшей общей подстроки, мне же надо было саму подстроку).
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.07.2011, 23:45
Ответы с готовыми решениями:

Работа со строками. Функции работы со строками
Дана строка символов. В заданном тексте определить позицию первой точки ‘ . ‘.

Типы оптимизация: черная оптимизация, серая оптимизация и белая оптимизация
Много много лет назад, на заре становления профессии &quot;оптимизатора&quot; в какой то умной книжке был...

Оптимизация работы
Есть большой файл с множеством формул массива, работа с ним довольно затруднительно. Вопрос такой,...

Оптимизация Работы С Тз
Есть две ТЗ с одинаковыми колонками: Товар, Цена, День, НачО, КонО, Приход, Расход Если в ТЗ1 и...

2
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
31.07.2011, 04:57 2
если алгоритм взят с википедии то тут уже нечего оптимизировать
Тем более, ты хочешь ворочать сотни милллионов строк и чтоб все быстро было? Такое только в сказках бывает..
даже простое сравнение в таких количествах займет те же минуты

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

Добавлено через 20 минут
еще попробуй вот такой вариант, в теории должно стать быстрей, проверить не на чем..
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
             
     public static string strLongestCommonSubstring(string str1, string str2)
        {
            if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2))
                return "";
 
            //string result = "";
           // var num = new List<int[]>(str1.Length);
            int[,] num = new int[str1.Length, str2.Length];
 
            int maxlen = 0;
            int saveIndex = 0;
            for (int i = 0; i < str1.Length; i++)
            {
//                 num.Add(new int[str2.Length]);
 
                for (int j = 0; j < str2.Length; j++)
                {
                    if (str1[i] != str2[j])
                        num[i,j] = 0;
                    else
                    {
                        if ((i == 0) || (j == 0))
                            num[i,j] = 1;
                        else
                            num[i,j] = 1 + num[i - 1,j - 1];
                        if (num[i,j] > maxlen)
                        {
                            maxlen = num[i,j];
                            saveIndex = i;
                            //result = str1.Substring(i - maxlen + 1, maxlen);
                        }
                    }
//                     if (i >= 2)
//                         num[i - 2] = null;
                }
            }
 
            return str1.Substring(saveIndex - maxlen + 1, maxlen);
        }
0
0 / 0 / 1
Регистрация: 24.07.2011
Сообщений: 10
31.07.2011, 12:25  [ТС] 3
Цитата Сообщение от m0nax Посмотреть сообщение
даже простое сравнение в таких количествах займет те же минуты
Извините, перепутал, там количество сравнений гораздо меньше Примерно в 1000 раз. Так что скорость работы не устраивает. Те же операции сравнения похожести дат на таких количествах у меня занимают теперь 0,2 секунды. А за код спасибо, попробую его.

Добавлено через 13 минут
Вообще, я хотел выслушать предложения по оптимизации моего метода AreSimilar - именно в нём могут быть костыли. Пока что в голову пришла идея в данном методе перед всеми вызовами strLongestCommonSubstring просто добавить следующее:

C#
1
2
            if (S1temp == S2temp)
                return true;
Должно будет уменьшить количество операций при почти одинаковых строках.
0
31.07.2011, 12:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.07.2011, 12:25
Помогаю со студенческими работами здесь

Оптимизация работы с БД
Прошло 5 недель, как я перешёл на веб-разработку. У меня много вопросов касающихся оптимизации....

Оптимизация работы с ТЗ
Есть две ТЗ Они, можно сказать, связаны один-к-многим При формировании печатной формы идет...

Планировщик-оптимизация работы
Скачал себе небольшое приложение , Power Notes ,кто работает на компьютере легко оценит удобность и...

Оптимизация работы Utorrent 3.3
На текущий момент Utorrent отказывается нормально скачивать файлы. Прочитал практически все советы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru