Click here to Skip to main content
15,881,852 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
my design of a bin packing problem is necessary of using an array of lists
(List<double>[n]), each list is list of doubles ..I want to search in each list in the array for equality ,
if repeated I want to... count++
to avoid repeated printed lines.
for example i want a result like that (3,4,3 count 3)instead of printing this line 3 times like that
(3,4,3).
(3,4,3).
(3,4,3).
and if any another ways recommended instead of (Sequence Equal) thanks a lot

What I have tried:

this piece of code
C#
if (resArrofLists[j].SequenceEqual( resArrofLists[j + 1]))

causes this exception
( System.ArgumentNullException: Value cannot be null.
Parameter name: second

C#
while (resArrofLists[index] != null)
{
	var lineString = new StringBuilder();
	var cutOfOnePole = resArrofLists[index];
	lineString.Append($"{(index+1)}: ");
	foreach (var length in cutOfOnePole)
	{
		
		lineString.Append($"{length} ");
	}

	
	int count = 1;

	for (int i = 0; i < resArrofLists.Length; i++)
	{

		for (int j = i; j < resArrofLists.Length ; j++)
		{

			if (resArrofLists[j].SequenceEqual( resArrofLists[j + 1]))
				count ++;
		}
	}

	lineString.Append($"Count: {count}");
}
Posted
Updated 24-Oct-22 23:30pm
v2

Thanks for your implementation and for revision for all these collections types
But I guess I didn't mention enough details about the algorithm..
My inputs are a group of 2 parameters let's say 2 integers are (required_lenght & required_quantiy)
Like that
(
Input.Add(length =7, quantity =3)
Input.Add(length =5, quantity =5)
The algorithm's function is to nesting this lengths with this quantity along( a bin or a 1-d pole) with a length of 12 meter
Until this my algorithm is good printing
But printing
(7, 5)
(7, 5)
(7, 5)
(5, 5)
I want to group these repeated results
Like that
(6,5) count 3
(5, 5)count 1


and this is the complete code ..but i deleted body of first and second methods as it is the algorithm of nesting ..if you want them i will send them immediately
i tried to specify it as much i can
and thank you


public class BinPacking
{

static List<double>[] firstFitDec(double[] Requred_lenght, int n, int c)
{


}
static List<double>[] firstFit(double[] Requred_lenght, int n, int c)
{

return resArrofLists;

}


public static void Main(String[] args)
{

var inputList = new List<inputmodel>();
// taking input from a user and add them to list (and repeating elements as requiered quantity)
while (true)
{
Console.WriteLine("Please enter your record with lengh and count like '2,3', and type 'e' to end or type 'a' to abort");
//take value from user
var userInput = Console.ReadLine();
if ( userInput.ToLower() == "a")
{
//end prgram
}
//to end user input at this point
if (userInput.ToLower() == "e")
break;

//parse value to array of two items
var userInputAsIntArray = userInput.Split(',').Select(x =>
{
if (double.TryParse(x, out var number))
return number;
return 0;
}).ToArray();

if (userInputAsIntArray.Length != 2 || userInputAsIntArray.Any(x => x == 0))
{
Console.WriteLine("something went wong");
break;
}
var inputModel = new InputModel { Leng = userInputAsIntArray[0], Coun = (int)userInputAsIntArray[1] };
inputList.Add(inputModel);
}
//convert list of input to arry of ints
var inputAsArray = inputList.Select(x =>
{
return Enumerable.Repeat(x.Leng, x.Coun);
}).SelectMany(a => a.ToArray()).ToArray();



int c = 12;
int n = inputAsArray.Length;

var resArrofLists = (firstFitDec(inputAsArray, n, c));

;
var index = 0;
while (resArrofLists[index] != null)
{
var lineString = new StringBuilder();
var cutOfOnePole = resArrofLists[index];
lineString.Append($"{(index+1)}: ");
foreach (var length in cutOfOnePole)
{

lineString.Append($"{length} ");
}


int count = 1;

lineString.Append($"Count: {count}");

Console.WriteLine(lineString);
index++;


for (int i = 0; i < resArrofLists.Length; i++)
{

for (int j = i; j < resArrofLists.Length; j++)
{
List<double> l1 = resArrofLists[j];
List<double> l2 = resArrofLists[j + 1];
if (l1.SequenceEqual(l2))
count++;
}
}
}
//Console.WriteLine($"all Count: {finalResult.SkipWhile(x=> x == null).Distinct(new ListCompare()).Count()}");
//Console.ReadLine();


}
 
Share this answer
 
Comments
Richard Deeming 25-Oct-22 8:40am    
If you want to update your question to add missing information, click the green "Improve question" link and edit your question. Do not post your update as a "solution" to your question!

Here is a novel way of achieving the result you require. Each array is converted into a string where each element is separated by a '*'. Matched strings are grouped together and the string and matches count are stored for each group. Finally, each string is deconstructed into an int[] using an extension method and the results are enumerated. It is probably not the best way to go but it was fun to write


C#
internal class Program
{
   private static void Main(string[] args)
   {
     List<int[]> arrayList = new() { new int[] { 1,12,3 }, new int[] { 4,33,5},
     new int[] { 1,12,3 }, new int[] { 4,33,5},new int[] { 4,33,5},new int[] { 6,7,8} };
     int[][] jaggedArray = arrayList.ToArray();
     StringBuilder sb = new();
     List<string> list = new();
     foreach (var array in jaggedArray)
      {
       sb.Clear();
       foreach (var i in array)
        {
          sb.Append(i).Append('*');
        }
        list.Add(sb.ToString().TrimEnd('*'));
         //eg Add("1*12*3")
      };
      var res = list.GroupBy(s => s, (key, matches) => (Id: key, Count: matches.Count()));
      List<(int[] array, int count)> result = new();
      //convert back to int array using a custom extension method
      foreach (var (Id, Count) in res) result.Add((Id.ToIntArray(), Count));
      foreach (var (array, count) in result)
       {
         Console.WriteLine($"{string.Join(',', array)}\t {count}");
       }
           /* prints
            1,12,3   2
            4,33,5   3
            6,7,8    1
           */
           Console.ReadLine();
       }

   }

   public static class Extensions
   {
     public static int[] ToIntArray(this string s)
     {
       string[] elements = s.Split('*');
       List<int> result = new();
       foreach (var e in elements)
        {
         result.Add(Convert.ToInt32(e));
        }
        return result.ToArray();
     }
   }
 
Share this answer
 
Quote:
causes this exception
( System.ArgumentNullException: Value cannot be null.
Parameter name: second

The SequenceEqual method requires two parameters. See Enumerable.SequenceEqual Method (System.Linq) | Microsoft Learn[^].
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900