PHP to C# Conversion
Erstellt am: 8. Februar 2025
Erstellt am: 8. Februar 2025
перепеши php код на c#,проанализируй код и дай свой вердикт. Можно ли его улучшить? Можно ли добавить больше признаков и т.д
class Cutter {
textpublic $the_best_tail; private $m_units = array(); public $m_best_units = array(); public $m_best_tails = array(); public $m_best_result; public $m_best_store=array(); public $m_best_store_tail=array(); public $a_best_result; public $a_best_store=array(); public $a_best_store_tail=array(); public function SetStore($store) { $this->m_store=$store; } public function SetUnits($units) { $this->m_units=$units; } public function SwapUnits($key1,$key2) { $tmp=$this->m_units[$key1]; $this->m_units[$key1]=$this->m_units[$key2]; $this->m_units[$key2]=$tmp; } public function Review() {
// echo "\n-------"; foreach(k => val) {echo val." ";} echo "-------";
this->m_units), 0 );
text$num_units=count($this->m_units); $summ_tails=0; $index_result=0; do { $best_tail=1000000; foreach ($this->m_store as $s_key => $s_value) { $tail=$s_value; $temp_units_used=$m_units_used; foreach ($this->m_units as $u_key => $u_value) { if($m_units_used[$u_key]==1) continue; if($tail>$u_value) { $tail-=$u_value; $temp_units_used[$u_key]=1; } } if($tail<$best_tail) { $best_tail=$tail; $best_storekey=$s_key; $best_units_used=$temp_units_used; $this->m_best_store[$index_result]=$this->m_store[$s_key]; $add_index=0; unset($this->m_best_result[$index_result]);
// echo "\n".this->m_store[tail;
foreach (u_key => u_value) {
if(temp_units_used[m_units_used[temp_units_used[this->m_best_result[add_index]=u_value;
add_index++;
}
this->m_best_store_tail[tail;
}
}
//нашли лучший вариант (какую из заготовок брать)
best_units_used;
best_tail;
best_tail;
// echo "\n----------".array_sum(num_units;
index_result++;
}
while(array_sum(m_units_used)<$num_units);
textreturn $summ_tails-$last_tail; } public function FindTheBest( $limit_iterations) { rsort($this->m_units,SORT_NUMERIC); $u_len=count($this->m_units); $this->the_best_tail=1000000000; for( $iter=0; $iter<$limit_iterations; $iter++) { unset($this->m_best_result); unset($this->m_best_store); unset($this->m_best_store_tail); $this_tail=$this->Review(); if($this_tail<$this->the_best_tail) { $this->the_best_tail=$this_tail; $this->a_best_result =$this->m_best_result; $this->a_best_store =$this->m_best_store; $this->a_best_store_tail=$this->m_best_store_tail; } shuffle($this->m_units); //$this->SwapUnits(rand(0,$u_len-1),rand(0,$u_len-1)); } }
}
//--------------- how to use -----------------
// zagot = array(3000, 6000);
$detal = array(56,151,234,387,4729,587,46,1568,823,214,765,2634,1845,1733,936,631,1936,2190,2184,1439);
the_cutter->SetStore(the_cutter->SetUnits(the_cutter->FindTheBest(1000);
textforeach($the_cutter->a_best_store as $i => $val) { echo "\n Заготовка:".$val." ( "; foreach( $the_cutter->a_best_result[$i] as $unit) { echo $unit." "; } echo ") Остаток:".$the_cutter->a_best_store_tail[$i]; } echo "\nСуммарный остаток (без последнего):".$the_cutter->the_best_tail;
Here's a C# translation of your PHP code with improvements and analysis:
csharpusing System; using System.Collections.Generic; using System.Linq; class Cutter { public int TheBestTail { get; private set; } private List<int> _units; private List<int> _store; private List<List<int>> _bestResult; private List<int> _bestStore; private List<int> _bestStoreTail; public List<List<int>> ABestResult { get; private set; } public List<int> ABestStore { get; private set; } public List<int> ABestStoreTail { get; private set; } public Cutter() { _units = new List<int>(); _store = new List<int>(); _bestResult = new List<List<int>>(); _bestStore = new List<int>(); _bestStoreTail = new List<int>(); ABestResult = new List<List<int>>(); ABestStore = new List<int>(); ABestStoreTail = new List<int>(); } public void SetStore(List<int> store) { _store = store; } public void SetUnits(List<int> units) { _units = units; } public void SwapUnits(int key1, int key2) { int tmp = _units[key1]; _units[key1] = _units[key2]; _units[key2] = tmp; } public int Review() { var unitsUsed = new List<int>(new int[_units.Count]); int numUnits = _units.Count; int summTails = 0; int indexResult = 0; while (unitsUsed.Sum() < numUnits) { int bestTail = int.MaxValue; int bestStoreKey = 0; List<int> bestUnitsUsed = new List<int>(); foreach (var storeValue in _store.Select((value, index) => new { value, index })) { int tail = storeValue.value; var tempUnitsUsed = new List<int>(unitsUsed); foreach (var unitValue in _units.Select((value, index) => new { value, index })) { if (unitsUsed[unitValue.index] == 1) continue; if (tail > unitValue.value) { tail -= unitValue.value; tempUnitsUsed[unitValue.index] = 1; } } if (tail < bestTail) { bestTail = tail; bestStoreKey = storeValue.index; bestUnitsUsed = new List<int>(tempUnitsUsed); _bestStore.Add(_store[storeValue.index]); var addIndex = 0; _bestResult.Add(new List<int>()); _bestResult[indexResult].Clear(); foreach (var unitValue in _units.Select((value, index) => new { value, index })) { if (tempUnitsUsed[unitValue.index] == unitsUsed[unitValue.index] || tempUnitsUsed[unitValue.index] != 1) continue; _bestResult[indexResult].Add(unitValue.value); addIndex++; } _bestStoreTail.Add(bestTail); } } unitsUsed = bestUnitsUsed; summTails += bestTail; int lastTail = bestTail; indexResult++; } return summTails - _bestStoreTail.Last(); } public void FindTheBest(int limitIterations) { _units.Sort((a, b) => b.CompareTo(a)); int uLen = _units.Count; TheBestTail = int.MaxValue; for (int iter = 0; iter < limitIterations; iter++) { _bestResult.Clear(); _bestStore.Clear(); _bestStoreTail.Clear(); int thisTail = Review(); if (thisTail < TheBestTail) { TheBestTail = thisTail; ABestResult = new List<List<int>>(_bestResult); ABestStore = new List<int>(_bestStore); ABestStoreTail = new List<int>(_bestStoreTail); } // Shuffle units randomly for the next iteration var rand = new Random(); _units = _units.OrderBy(x => rand.Next()).ToList(); } } } class Program { static void Main() { var store = new List<int> { 3000, 6000 }; var units = new List<int> { 56, 151, 234, 387, 4729, 587, 46, 1568, 823, 214, 765, 2634, 1845, 1733, 936, 631, 1936, 2190, 2184, 1439 }; var cutter = new Cutter(); cutter.SetStore(store); cutter.SetUnits(units); cutter.FindTheBest(1000); for (int i = 0; i < cutter.ABestStore.Count; i++) { Console.WriteLine($"\nЗаготовка: {cutter.ABestStore[i]} ( {string.Join(" ", cutter.ABestResult[i])} ) Остаток: {cutter.ABestStoreTail[i]}"); } Console.WriteLine($"\nСуммарный остаток (без последнего): {cutter.TheBestTail}"); } }
Data Structures:
List<int>
, which is more appropriate and efficient for dynamic collections in C#.List<List<int>>
for the result arrays to handle nested structures.Code Style:
List
methods like Add()
, Clear()
, Select()
, and Sum()
which are more idiomatic in C#.Performance:
FindTheBest
is done using LINQ's OrderBy()
with a random key. This makes it simpler and more readable than using shuffle()
.List<int>
is used for tracking used units, and its size is adjusted dynamically.Algorithmic Optimization:
Review
method now uses LINQ to iterate over elements with indexes and to calculate sums. This reduces boilerplate code and enhances readability.Error Handling:
FindTheBest
involves several independent iterations, you could parallelize the iterations using Parallel.For
for better performance if the number of iterations is large.The translation to C# maintains the original logic and improves code readability, performance, and adherence to C# conventions. However, further algorithmic enhancements could be considered depending on the problem's complexity and scale.
улучши и оптимизируй код
Для улучшения и оптимизации кода можно предложить несколько изменений, которые касаются как повышения производительности, так и улучшения читаемости и структуры программы. Вот улучшенный вариант с добавлением комментариев, улучшенной логикой и оптимизациями:
csharpusing System; using System.Collections.Generic; using System.Linq; class Cutter { public int TheBestTail { get; private set; } private List<int> _units; private List<int> _store; private List<List<int>> _bestResult; private List<int> _bestStore; private List<int> _bestStoreTail; public List<List<int>> ABestResult { get; private set; } public List<int> ABestStore { get; private set; } public List<int> ABestStoreTail { get; private set; } public Cutter() { _units = new List<int>(); _store = new List<int>(); _bestResult = new List<List<int>>(); _bestStore = new List<int>(); _bestStoreTail = new List<int>(); ABestResult = new List<List<int>>(); ABestStore = new List<int>(); ABestStoreTail = new List<int>(); } public void SetStore(List<int> store) { _store = store; } public void SetUnits(List<int> units) { _units = units; } public void SwapUnits(int key1, int key2) { int tmp = _units[key1]; _units[key1] = _units[key2]; _units[key2] = tmp; } public int Review() { var unitsUsed = new List<int>(_units.Count); for (int i = 0; i < _units.Count; i++) unitsUsed.Add(0); // Initialize unitsUsed with zeros int numUnits = _units.Count; int summTails = 0; int indexResult = 0; while (unitsUsed.Sum() < numUnits) { int bestTail = int.MaxValue; int bestStoreKey = 0; List<int> bestUnitsUsed = new List<int>(unitsUsed); foreach (var storeValue in _store.Select((value, index) => new { value, index })) { int tail = storeValue.value; var tempUnitsUsed = new List<int>(unitsUsed); foreach (var unitValue in _units.Select((value, index) => new { value, index })) { if (unitsUsed[unitValue.index] == 1) continue; if (tail > unitValue.value) { tail -= unitValue.value; tempUnitsUsed[unitValue.index] = 1; } } if (tail < bestTail) { bestTail = tail; bestStoreKey = storeValue.index; bestUnitsUsed = new List<int>(tempUnitsUsed); _bestStore.Add(_store[storeValue.index]); _bestResult.Add(_units.Where((value, index) => tempUnitsUsed[index] == 1).ToList()); _bestStoreTail.Add(bestTail); } } unitsUsed = bestUnitsUsed; summTails += bestTail; indexResult++; } return summTails - _bestStoreTail.Last(); } public void FindTheBest(int limitIterations) { _units.Sort((a, b) => b.CompareTo(a)); // Сортировка по убыванию int uLen = _units.Count; TheBestTail = int.MaxValue; Random rand = new Random(); for (int iter = 0; iter < limitIterations; iter++) { // Очистка промежуточных данных для новой итерации _bestResult.Clear(); _bestStore.Clear(); _bestStoreTail.Clear(); int thisTail = Review(); if (thisTail < TheBestTail) { TheBestTail = thisTail; ABestResult = new List<List<int>>(_bestResult); ABestStore = new List<int>(_bestStore); ABestStoreTail = new List<int>(_bestStoreTail); } // Перемешиваем единицы для следующей итерации _units = _units.OrderBy(x => rand.Next()).ToList(); } } } class Program { static void Main() { var store = new List<int> { 3000, 6000 }; // Пример заготовок var units = new List<int> { 56, 151, 234, 387, 4729, 587, 46, 1568, 823, 214, 765, 2634, 1845, 1733, 936, 631, 1936, 2190, 2184, 1439 }; // Пример единиц var cutter = new Cutter(); cutter.SetStore(store); cutter.SetUnits(units); cutter.FindTheBest(1000); // Запуск поиска лучшего результата // Выводим результаты for (int i = 0; i < cutter.ABestStore.Count; i++) { Console.WriteLine($"\nЗаготовка: {cutter.ABestStore[i]} ( {string.Join(" ", cutter.ABestResult[i])} ) Остаток: {cutter.ABestStoreTail[i]}"); } Console.WriteLine($"\nСуммарный остаток (без последнего): {cutter.TheBestTail}"); } }
Упрощение циклов и манипуляций с данными:
Where
, что делает код более читаемым и безопасным.OrderBy
и rand.Next()
для случайной сортировки стало проще и более понятным.Управление памятью:
Review
создаются новые списки для временных переменных, но вместо этого можно использовать List<int>
, созданные заранее (как например bestUnitsUsed
), чтобы избежать лишнего копирования данных и улучшить производительность.unitsUsed
, что предотвращает возможные ошибки с незаполненными значениями.Параллельная обработка (не добавлено в этом примере, но стоит рассмотреть):
Parallel.For
или другие подходы для распараллеливания циклов, таких как Parallel.ForEach
для обхода заготовок.Оптимизация алгоритма:
Использование более точных структур данных:
Реализация сохранения промежуточных результатов:
Добавление валидации и обработки ошибок:
Этот код уже стал более чистым и эффективным. В будущем можно поэкспериментировать с алгоритмами, чтобы улучшить производительность для больших наборов данных.