Не могу правильно поставить условие
for (int i = 0; i < file1.Count; i++)
{
for (int j = 0; j < file2.Count; j++)
{
// Удаленные строки показываются красным цветом, добавленные - желтым, неизмененные - зеленым.
if (file1[i] == file2[j])// НЕ измененая строка - зеленая
{
ListViewItem li = new ListViewItem();
li.ForeColor = Color.Green;
li.Text = file1[i];
listView1.Items.Add(li);
break;
}
if (file1[i] != file2[j]) // Удаленные строки показываются красным цветом,
{
ListViewItem li = new ListViewItem();
li.ForeColor = Color.Red;
li.Text = file1[i];
listView1.Items.Add(li);
break;
}
//else if ...// добавленные - желтым,
}
}
Удаленные строки показываются красным цветом, добавленные - желтым, неизмененные - зеленым. У меня 2 списка
List<string> file1 = new List<string>();
List<string> file2 = new List<string>();
Я ставлю условие что в file найдена строка как и file2 то зеленым, если нет такой то красным ВОТ только цвет изменяется на первой строчке далее идет все красное, а про измененные даже не знаю
Весь код программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AnalyzerTwoTextFiles
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<string> file1 = new List<string>();
List<string> file2 = new List<string>();
private void btn_generation_Click(object sender, EventArgs e)
{
GetFile1();
WriteToFile();
GetFile2();
listView1.Clear();
for (int i = 0; i < file1.Count; i++)
{
for (int j = 0; j < file2.Count; j++)
{
// Удаленные строки показываются красным цветом, добавленные - желтым, неизмененные - зеленым.
if (file1[i] == file2[j])// НЕ измененая строка - зеленая
{
ListViewItem li = new ListViewItem();
li.ForeColor = Color.Green;
li.Text = file1[i];
listView1.Items.Add(li);
break;
}
if (file1[i] != file2[j]) // Удаленные строки показываются красным цветом,
{
ListViewItem li = new ListViewItem();
li.ForeColor = Color.Red;
li.Text = file1[i];
listView1.Items.Add(li);
break;
}
//else if ...// добавленные - желтым,
}
}
}
private List<string> GetFile1()
{
file1.Clear();
using (StreamReader sr = new StreamReader("File1.txt"))
{
while (!sr.EndOfStream)
{
string[] s = sr.ReadLine().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
string arStr;
arStr = "";
for (int i = 0; i<s.Length;i++)
{
arStr += s[i] + " ";
}
file1.Add(arStr);
}
return file1;
}
}
private void WriteToFile()
{
using (FileStream fstream = new FileStream("file2.txt", FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fstream))
{
string strfile2 = textBox1.Text;
fstream.Seek(0, SeekOrigin.End);
sw.WriteLine(textBox1.Text);
}
}
}
private List<string> GetFile2()
{
file2.Clear();
using (StreamReader sr = new StreamReader("File2.txt"))
{
while (!sr.EndOfStream)
{
string[] s = sr.ReadLine().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
string arStr;
arStr = "";
for (int i = 0; i < s.Length; i++)
{
arStr += s[i] + " ";
}
file2.Add(arStr);
}
return file2;
}
}
}
}
Пример как должен выглядеть результат рабочий программы
Ссылка на проект - https://github.com/wargerun/AnalyzerTwoTextFiles/
Первый файл (образец)
Первая строка.
Вторая строка.
Третья строка.
Второй файл
Первая строка.
3-я строка.
Еще одна строка.
Получилось так
Код такой
/// <summary>
/// Строка
/// </summary>
class Line
{
public enum LineType
{
Unchanged, //неизмененная
Added, //добавленная
Deleted, //удаленная
}
public string Text { get; set; }
public LineType Type { get; set; }
public override string ToString()
{
return $"{Text} : {Type}";
}
}
/// <summary>
/// Подсобный класс для сверки строк
/// </summary>
class LineComparer : IEqualityComparer<Line>
{
public bool Equals(Line x, Line y)
{
return x.Text.Equals(y.Text);
}
public int GetHashCode(Line obj)
{
return obj.Text.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("ConsoleAppLinesComparison");
Console.WriteLine();
var originFile = @"D:\fileOrigin.txt";
var otherFile = @"D:\fileOther.txt";
List<Line> originLines = GetLines(originFile);
List<Line> otherLines = GetLines(otherFile);
List<Line> resultLines = CheckLines(originLines, otherLines);
PrintLines(resultLines);
Console.ReadKey();
}
/// <summary>
/// Чтение файла в коллекцию строк
/// </summary>
/// <param name="file">путь к файлу</param>
/// <returns></returns>
private static List<Line> GetLines(string file)
{
List<Line> result = new List<Line>();
try
{
foreach (var line in File.ReadAllLines(file))
{
result.Add(new Line { Text = line });
}
}
catch (Exception ex)
{
Console.WriteLine($"Чтение {file} c ошибкой: {ex.Message}");
}
return result;
}
/// <summary>
/// Сверка двух коллекций строк,
/// простановка соответ. типов строкам.
/// Возвращает объединенную коллекцию строк
/// </summary>
/// <param name="originLines">коллекция образец</param>
/// <param name="otherLines">коллекция для сверки</param>
/// <returns>объединенная коллекция строк без повторений</returns>
private static List<Line> CheckLines(List<Line> originLines, List<Line> otherLines)
{
//все строки которых нет в другом файле
var exceptOriginLines = originLines.Except(otherLines, new LineComparer());
foreach (var line in exceptOriginLines)
{
line.Type = Line.LineType.Deleted;
}
//все строки которых нет в оригинальном файле
var exceptOtherLines = otherLines.Except(originLines, new LineComparer());
foreach (var line in exceptOtherLines)
{
line.Type = Line.LineType.Added;
}
//объединенная последовательность (без повторений)
var unionLines = originLines.Union(otherLines, new LineComparer());
return unionLines.ToList();
}
private static void PrintLines(List<Line> resultLines)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Неизменные строки");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Удаленные строки");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Добавленные строки");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(new string('=', 20));
Console.WriteLine();
foreach (var line in resultLines)
{
if (line.Type == Line.LineType.Unchanged)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(line.Text);
}
else if (line.Type == Line.LineType.Added)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(line.Text);
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(line.Text);
}
Console.ForegroundColor = ConsoleColor.White;
}
}
}
Определим результат операции
public class CompareStringResult
{
public enum ActionType { Deleted, Added, NotChanged };
public ActionType Action { get; }
public string Data { get; }
public CompareStringResult(string data, ActionType action)
{
Data = data;
Action = action;
}
}
Код для сравнения прост, работает линейное время
public IEnumerable<CompareStringResult> Compare(string[] oldValues, string[] newValues)
{
var result = new List<CompareStringResult>();
var allLines = new HashSet<string>(oldValues.Union(newValues));
var oldSet = new HashSet<string>(oldValues);
var newSet = new HashSet<string>(newValues);
foreach (var line in allLines)
{
var action = CompareStringResult.ActionType.NotChanged;
if (oldSet.Contains(line) && !newSet.Contains(line)) action = CompareStringResult.ActionType.Deleted;
if (!oldSet.Contains(line) && newSet.Contains(line)) action = CompareStringResult.ActionType.Added;
result.Add(new CompareStringResult(line, action));
}
return result;
}
Как проверить
var oldV = Enumerable.Range(0, 10).Select(x=>x.ToString()).ToArray();
var newV = Enumerable.Range(5, 10).Select(x=>x.ToString()).ToArray();
foreach(var r in Compare(oldV, newV))
{
Console.WriteLine($"{r.Action} - {r.Data}");
}
Вывод
Deleted - 0
Deleted - 1
Deleted - 2
Deleted - 3
Deleted - 4
NotChanged - 5
NotChanged - 6
NotChanged - 7
NotChanged - 8
NotChanged - 9
Added - 10
Added - 11
Added - 12
Added - 13
Added - 14
Добавлю ещё один ответ.
У двух существующих ответов есть плюсы - маленький расход памяти, линейная сложность, но при этом и есть минус - они никак не работают с изначальным порядком строк в исходнике и приёмнике.
Чтобы учитывать этот порядок, можно воспользоваться разными алгоритмами. Я попробую воспользоваться самым простым, что знаю - Расстояние Левенштейна, который мы немного подредактируем под нашу задачу. Сам алгоритм расписан на википедии, повторять его здесь смысла нет.
Итак, что мы в алгоритм изменим:
1) Начнем с того, что расстояние Левенштейна изначально предназначено для символов в тексте. Но мы будем вместо символа в тексте сравнивать строку в наборе строк.
2) Замена одной строки на другую в оригинале считается одной операцией. Но мы будем считать, что это 2 операции (удалить старую строку, добавить новую).
Результат операции будем хранить в следующем классе:
public class CompareStringResult
{
public enum ActionType { Deleted, Added, Changed, NotChanged };
public ActionType Action { get; }
public string OldValue { get; }
public string NewValue { get; }
public CompareStringResult(string oldValue, string newValue, ActionType action)
{
OldValue = oldValue;
NewValue = newValue;
Action = action;
}
}
Вот и, по сути, все. Приступим!
public IEnumerable<CompareStringResult> Compare(string[] oldValues, string[] newValues)
{
var board = new int[oldValues.Length + 1, newValues.Length + 1];
for (var i = 0; i < board.GetLength(0); i++) board[i, 0] = i;
for (var i = 0; i < board.GetLength(1); i++) board[0, i] = i;
// подготовка таблицы изменений
for (var i = 1; i < board.GetLength(0); i++)
{
for (var j = 1; j < board.GetLength(1); j++)
{
var stringsEquals = string.CompareOrdinal(oldValues[i - 1], newValues[j - 1]) == 0;
var add = (stringsEquals ? 0 : 1);
board[i, j] = Math.Min(board[i - 1, j - 1] + add * 2, Math.Min(board[i - 1, j] + 1, board[i, j - 1] + 1));
}
}
// Идея такая: раз нижний правый угол - наша конечная цель, то, чтобы найти кратчайший путь изменений, нам придется пройти от конца в начало. Стартуем в нижнем правом углу, заканчиваем в верхнем левом. Но, так как мы движемся в обратном направлении, то я использовал стек для реверса результата к прямому порядку в конце функции.
var stack = new Stack<CompareStringResult>();
var ii = board.GetLength(0) - 1;
var jj = board.GetLength(1) - 1;
// прогулка из правого нижнего угла таблицы в верхний левый по пути с минимальной суммой
while (ii > 0 && jj > 0)
{
var max = board[ii, jj];
// Очевидно, двигаться мы можем вверх, влево или вверх-влево. Смотрим где наименьший элемент, туда и идем.
var min = Math.Min(board[ii - 1, jj - 1], Math.Min(board[ii - 1, jj], board[ii, jj - 1]));
if (min == board[ii - 1, jj - 1])
{
if (min != max)
{
stack.Push(new CompareStringResult(oldValues[ii - 1], newValues[jj - 1], CompareStringResult.ActionType.Changed));
}
else
stack.Push(new CompareStringResult(newValues[jj - 1], newValues[jj - 1], CompareStringResult.ActionType.NotChanged));
ii--;
jj--;
}
else if (min == board[ii - 1, jj])
{
if (min != max)
stack.Push(new CompareStringResult(oldValues[ii - 1], null, CompareStringResult.ActionType.Deleted));
else
stack.Push(new CompareStringResult(oldValues[ii - 1], newValues[jj], CompareStringResult.ActionType.NotChanged));
ii--;
}
else if (min == board[ii, jj - 1])
{
if (min != max)
stack.Push(new CompareStringResult(null, newValues[jj - 1], CompareStringResult.ActionType.Added));
else
stack.Push(new CompareStringResult(oldValues[ii], newValues[jj - 1], CompareStringResult.ActionType.NotChanged));
jj--;
}
}
// Если уперлись в левую стенку, но ещё не дошли до верха
while (ii > 0)
{
var max = board[ii, jj];
var min = board[ii - 1, jj];
if (min != max)
stack.Push(new CompareStringResult(oldValues[ii - 1], null, CompareStringResult.ActionType.Deleted));
else
stack.Push(new CompareStringResult(oldValues[ii - 1], newValues[jj], CompareStringResult.ActionType.NotChanged));
ii--;
}
// Если уперлись в потолок, но ещё не в левом углу
while (jj > 0)
{
var max = board[ii, jj];
var min = board[ii, jj - 1];
if (min != max)
stack.Push(new CompareStringResult(null, newValues[jj - 1], CompareStringResult.ActionType.Added));
else
stack.Push(new CompareStringResult(oldValues[ii], newValues[jj - 1], CompareStringResult.ActionType.NotChanged));
jj--;
}
return stack;
}
Результат:
Хочу обратить внимание, что сложность алгоритма, как и затраты на память, стали гораздо больше чем в других ответах (N*M), но и качество полученного расстояния выше.
Полный текст примера доступен тут
Виртуальный выделенный сервер (VDS) становится отличным выбором
Стоит задача сделать программу мониторинга железок по SNMP(не спрашивайте зачем, сам в шоке) Планирую использовать c# и библиотеку SNMP lexМониториться...
Изучаю тему IoC и DIВсё вроде понял зачем как и почему пока не дошел до IoC контейнера Unity
Например, у меня есть txt файл на удалённом компьютере в его открытой сетевой папкеНужно локально считать этот файл
Всех приветствую, вопрос такой, изучаю этот парсер, вот страница, которую я хочу разобратьВот мой код