andrew898701 Ответов: 2

Совет по минимизации вложенных циклов?


Привет,

Я пишу код для обработки номеров деталей с помощью цифрового сканера. Цифровой сканер считывает номера деталей на этикетке, и если деталь указана на дисплее программы "datagridview", то он сохраняет их как "отсканированные" (здесь не показано), но если они не найдены, то возвращает ошибку. Этот код предназначен для улавливания некоторых распространенных ошибок, которые иногда делает сканер, чтобы предотвратить количество раз, когда пользователю нужно вручную исправить их.

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

int index;
     index = 0;
     string[] rejected = new string[10];
     foreach (DataGridViewRow row in dgView.Rows)
            {
                Fix:
                if ((string)row.Cells[1].Value != txtScannedIn.Text.Trim())
                {
                    string editedtext; 
                    string originaltext;
                    originaltext = txtScannedIn.Text.Trim();
                    editedtext = ScanFix(txtScannedIn.Text, rejected); //trying to fix the text

                    if ((string)row.Cells[1].Value == editedtext)//this code ensures a correction is right
                    { 
                        MessageBoxButtons buttons = MessageBoxButtons.YesNoCancel;
                        DialogResult result = MessageBox.Show("Unfound scan " + originaltext + " was autocorrected to " + editedtext + "\n" + "\n" + "Press enter to confirm this change" + "\n" + "Press No suggest new part" + "\n" + "Press Cancel to exit dialog", "Suggested Replacement", buttons);
                        if (result == DialogResult.Yes)// Accepted corrections
                                                       // pass through
                        {
                            txtScannedIn.Text = editedtext;
                        }
                        else if (result == DialogResult.No)//Requesting new correction from datagrid
                        {                                   
                            rejected[index] = editedtext;//rejected part is notated for ScanFix method to not suggest again.
                            index++;
                            goto Fix;
                        }
                        else if (result == DialogResult.Cancel)
                        {
                            break;
                        }
                    }
                }



Ниже приведен фактический метод, который фиксирует сканирование. По сути, он циклически проходит через сетку данных и использует алгоритм расстояния строк Дамерау-Левенштейна "StringDistance", чтобы определить, на сколько изменений находится не найденное сканирование от одного в сетке. Существует два цикла foreach, так что он сначала сканирует и возвращает замену 1 символа, а затем 2 символа. Если у кого-то есть какие-либо советы относительно потенциально более эффективного способа достижения этой цели, я был бы очень признателен вам за помощь.

public string ScanFix(string NotFound, string[] rejected)
        {
            
            foreach (DataGridViewRow row in dgView.Rows)
            {
                int guess;
                guess = StringDistance(NotFound, (string)row.Cells[1].Value);//Compare NotFound ID to grid
                if (guess <= 1 && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false) 
                {                                                                                                   
                    return (string)row.Cells[1].Value;
                }
                if (NotFound.Contains((string)row.Cells[1].Value) && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false)//Sometimes the right part will be scanned with other gunk from the label
                {
                    return (string)row.Cells[1].Value;
                }
            }
            foreach (DataGridViewRow row in dgView.Rows)
            {
                int secondguess;
                secondguess = StringDistance(NotFound, (string)row.Cells[1].Value);
                if (secondguess <= 2 && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false)// it then tries the same process for the first two character replacement. 
                {
                    return (string)row.Cells[1].Value;
                }
            }
            return NotFound;
        }


Что я уже пробовал:

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

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

Большое спасибо!

2 Ответов

Рейтинг:
2

BillWoodruff

Я мог бы сломать свой мозг, пытаясь понять, что делает этот сложный код :)

Несколько вещей выскакивают на меня при быстром осмотре:

1 Вы вызываете trim на входе более одного раза

2 в цикле через строки DGV вы можете вызвать 'ScanFix, который, по-видимому, делает еще один цикл через строки ?

3 Вы читаете строку string)row.Ячейки[1].Значение несколько раз: сохраните его в переменной и повторно используйте.

4 Можно ли пересечь строки и создать структуру данных, содержащую те, которые нуждаются в исправлении, затем выполнить исправление на этом подмножестве, а затем обновить что угодно ?

удачи вам !


Рейтинг:
0

Patrice T

Цитата:
Совет по минимизации вложенных циклов?

Вопрос начинается плохо, потому что есть нет вложенных циклов в этом коде!

    Fix:
...
                goto Fix;

Вообще говоря, использование меток и goto в коде-плохая идея, потому что это делает код запутанным (спагетти-код) и трудным для отладки и оптимизации.
В тех редких случаях, когда я прибегаю к goto, это происходит после отладки и оптимизации, когда goto приведет к ускорению кода.


BillWoodruff

Патрис, он использует циклы foreach, а также метки/goto.