Запись минус и плюс строк в переменную C# textbox и MySQL
В продолжение моего вопроса Сравнение строк из массива (textbox1) с строками из MySQL C#
Пытаюсь сравнить строки из базы данных и дальше разделить на "минус-слова" и "плюс-слова". Минус-слова — это слова, которые уже существуют в базе данных (проверяется путем сравнения строки из textbox1 и строк из базы данных), "плюс-слова" — строки, которых нет в базе данных (они должны сохраняться в новую коллекцию таких "плюс-слов" и выводить в label общее кол-во плюс-слов, которые существуют в этой коллекции.
В моем случае почему-то попадает строка из "минус-слов" в коллекцию "плюс-слов", я пробовал использовать оператор прерывания return, но это явно не то.
Пример на скриншотах ниже
База данных с тестовыми номерами (которые и проверяются в программе на схожесть)

Код:
private void button1_Click(object sender, EventArgs e)
{
//-------------запуск таймера------------------------------------------------------------------------------------//
Stopwatch sw_total = new Stopwatch();
sw_total.Start();
try
{
string connStr =
"server=localhost;" +
"user=root;" +
"database=test;" +
"password=;";
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
string sql = "SELECT `numbers` FROM numbers";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader reader = cmd.ExecuteReader();
int nRows = 0; // number of rows in mysql database
int minusWords = 0;
// ---------------------- Считываем строки из textbox1 -----------------------------------
String[] s = textBox1.Text.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
HashSet<string> str = new HashSet<string>();
HashSet<string> RowsString = new HashSet<string>();
HashSet<string> MinusString = new HashSet<string>();
HashSet<string> PlusString = new HashSet<string>();
for (int k = 0; k < s.Length; ++k)
{
str.Add(s[k]);
}
if (!reader.HasRows)
MessageBox.Show("Таблица пуста");
else
{
while (reader.Read())
{
string number = reader["numbers"].ToString();
RowsString.Add(number);
nRows++;
}
foreach (string _str in str)
{
foreach(string _rows in RowsString)
{
if (_str.Contains(_rows) == true)
{
minusWords++;
MessageBox.Show("OK");
lblMinusWords.Text = $"Минус-слов: {minusWords}";
}
else
{
if (_str.Contains(_rows) != true)
PlusString.Add(_str);
}
}
}
MessageBox.Show($"All rows == {nRows}");
MessageBox.Show("Last in MySQL: " + RowsString.Last()
.Trim()
.ToString());
reader.Close();
conn.Close();
}
// ---------------------------------- плюс строки -------------------------------------
int pCount = 0;
foreach (var count in PlusString)
{
MessageBox.Show(count);
pCount++;
}
lblPlusWords.Text = $"Плюс-слов: {pCount}";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
//-------------вывод результата таймера----------------------------------------------------------------------//
sw_total.Stop();
lblTime.Text = ("Reading: " + sw_total.ElapsedMilliseconds + " ms");
}
Ответы (2 шт):
По сравнению с предыдущим вопросом алгоритм даже упрощается, главное вам надо понять почему и как использование HashSet упрощает поиск в нём слова и позвоняет снизить сложность алгоритма с O(N^2) до O(N).
var stringsFromDb = new string[] { "мама", "мыла", "раму" };
var stringsFromTxtBox = new string[] { "мама", "но", "раму", "же", "есть", "надо!" };
var set = new HashSet<string>(stringsFromDb);
int minusWords = 0;
int plusWords = 0;
for (var i = 0; i < stringsFromTxtBox.Length; i++)
{
if (set.Contains(stringsFromTxtBox[i]))
{
plusWords++;
Console.WriteLine($"слово '{stringsFromTxtBox[i]}' содержится в базе");
// TODO занести в HashSet<string> PlusString
}
else
{
minusWords++;
Console.WriteLine($"слово '{stringsFromTxtBox[i]}' НЕ содержится в базе");
// TODO занести в HashSet<string> MinusString
}
}
Console.WriteLine(minusWords);
Console.WriteLine(plusWords);
А в остальном решение выдаёт тот же самый ответ:
Вы не указали, имеет ли столбец с номерами-строками ограничение на уникальность.
Решение
Предполагается уникальность столбца с номерами-строками. try-catch и прочие проверки не использовал, т.к. это пример.
private void button1_Click(object sender, EventArgs e)
{
string connStr = "...";
using (MySqlConnection conn = new MySqlConnection(connStr))
{
conn.Open();
List<string> userNumbers = textBox1.Text
.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
.ToList();
string sql = "SELECT number FROM numbers";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader reader = cmd.ExecuteReader();
int minusCount = 0; // Которые есть в БД.
int plusCount = userNumbers.Count; // Которых нет в БД.
int totalCount = 0; // Всего в БД.
string dbNumber;
while (reader.Read())
{
totalCount++;
dbNumber = reader["number"].ToString();
if (userNumbers.Any(n => n == dbNumber))
{
userNumbers.Remove(dbNumber);
minusCount++;
plusCount--;
}
}
label1.Text = $"Всего строк в БД: {totalCount}";
label2.Text = $"Минус-строк: {minusCount}";
label3.Text = $"Плюс-строк: {plusCount}";
}
}


