Max value function for an array - c#

I have read in a file, sorted the file by into three columns and put all of the data in each columns into 3 arrays. I now need to make a method to get the max value out of the second column array. This is the code:
static void Main(string[] args)
{
string file1 = System.IO.File.ReadAllText(#"C:\file1.txt");
List<double> Array1 = new List<double>();
List<double> Array2 = new List<double>();
List<double> Array3 = new List<double>();
IEnumerable<string> lines = File.ReadLines(#"C:\File1.txt");
foreach (string line in lines)
{
string[] columns = line.Split(',');
if (columns.Length != 3)
{
continue; // skips this line
}
Array1.Add(Convert.ToDouble(columns[0]));
Array2.Add(Convert.ToDouble(columns[1]));
Array3.Add(Convert.ToDouble(columns[2]));
}
Console.WriteLine(Max(Array1.ToArray()));
}
static double Max (double[] x)
{
double maxValue = x.Max();
return maxValue;
}
ERROR: Type or namespace definition, or end-of-file expected.
I need to fix the Max Method and also I do not know how to Say that it is Array 2 that we need to get the max value of. I then need to go back up to the main and Use the Max Method to get the maximum value of array 2. Clearly their are beginners errors in the Max function but I have researched the problem andI am unsure of how to proceed.

static double Max (double[] x)
{
double[] x // This line shouldn't be here
double maxValue = x.Max();
return maxValue;
}
You're declaring double[] x twice, in the parameter as well as in the method. This will mess things up.
Also, try not to have the same name for your method as the one from the API, just to make code easier to read.
Lastly, you never called the method from main. :P

namespace Your_Name_Space
{
class Your_Program
{
public static void Main(string[] args)
{
string file1 = System.IO.File.ReadAllText(#"D:\file1.txt");
List<double> Array1 = new List<double>();
List<double> Array2 = new List<double>();
List<double> Array3 = new List<double>();
IEnumerable<string> lines = File.ReadLines(#"D:\File1.txt");
foreach (string line in lines)
{
string[] columns = line.Split(',');
if (columns.Length != 3)
{
continue; // skips this line
}
Array1.Add(Convert.ToDouble(columns[0]));
Array2.Add(Convert.ToDouble(columns[1]));
Array3.Add(Convert.ToDouble(columns[2]));
}
Console.WriteLine(Max(Array1.ToArray()));
Console.ReadKey();
}
public static double Max(double[] x)
{
double maxValue = x.Max();
return maxValue;
}
}
}
file1.text's content is like below :
1, 2, 3
4, 5, 6
7, 8, 9
All your codes ran. When the above code is compiled and executed, it produces the following result:
7
'end-of-file expected' error's reason is braces excess. You should control your braces. And value 7 isn't second coloumn.

Related

Searching for all combinations of numbers from a set of numbers which equal a target, code misses some but not all

I used this question Find out which combinations of numbers in a set add up to a given total which uses a C# example to attempt to find all the possible combinations of numbers which add up to a given number.
I used the code as provided and have attempted to understand it and I think I do, however, I can't figure out why this error is occurring.
Here is the setup:
public class Program
{
public static void Main(string[] args)
{
// subtotal list
List<double> totals = new List<double>(new double[] { 17.5, 14.3, 10.9, 7.8, 6.3, 3.8, 3.2, 2.7, 1.8, 1.0 });
List<double> totals2 = new List<double>(new double[] { 17.5, 14.3, 7.8, 6.3, 3.2, 1.8});
// get matches
List<double[]> results = Knapsack.MatchTotal(50.9, totals2);
// print results`
foreach (var result in results)
{
Console.WriteLine(string.Join(",", result));
}
Console.WriteLine("Done.");
Console.ReadKey();
}
}
and the main bulk of the code is unchanged from the example.
public class Knapsack
{
internal static List<double[]> MatchTotal(double theTotal, List<double> subTotals)
{
List<double[]> results = new List<double[]>();
while (subTotals.Contains(theTotal))
{
results.Add(new double[1] { theTotal });
subTotals.Remove(theTotal);
}
// if no subtotals were passed
// or all matched the Total
// return
if (subTotals.Count == 0)
return results;
subTotals.Sort();
double mostNegativeNumber = subTotals[0];
if (mostNegativeNumber > 0)
mostNegativeNumber = 0;
// if there aren't any negative values
// we can remove any values bigger than the total
if (mostNegativeNumber == 0)
subTotals.RemoveAll(d => d > theTotal);
// if there aren't any negative values
// and sum is less than the total no need to look further
if (mostNegativeNumber == 0 && subTotals.Sum() < theTotal)
return results;
// get the combinations for the remaining subTotals
// skip 1 since we already removed subTotals that match
for (int choose = 2; choose <= subTotals.Count; choose++)
{
// get combinations for each length
IEnumerable<IEnumerable<double>> combos = Combination.Combinations(subTotals.AsEnumerable(), choose);
// add combinations where the sum mathces the total to the result list
results.AddRange(from combo in combos
where combo.Sum() == theTotal
select combo.ToArray());
}
return results;
}
}
public static class Combination
{
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int choose)
{
return choose == 0 ? // if choose = 0
new[] { new T[0] } : // return empty Type array
elements.SelectMany((element, i) => // else recursively iterate over array to create combinations
elements.Skip(i + 1).Combinations(choose - 1).Select(combo => (new[] { element }).Concat(combo)));
}
}
I have provided the set of numbers which is in totals which are used to try and calculate the total.
I entered 50.9 as the total and return no results.
The second set of numbers totals2 is a set of numbers which add up to 50.9 and they are a subset of totals. This also fails to return a result for 50.9
For some reason the code is unable to find 50.9 in the master set or in the subset (which itself sums to 50.9).
I can't figure out why it does this, can anyone tell me?

C# Populate An Array with Values in a Loop

I have a C# console application where an external text file is read. Each line of the file has values separated by spaces, such as:
1 -88 30.1
2 -89 30.1
So line one should be split into '1', '-88', and '30.1'.
What I need to do is to populate an array (or any other better object) so that it duplicate each line; the array should have 3 elements per row. I must be having a brain-lock to not figure it out today. Here's my code:
string line;
int[] intArray;
intArray = new int[3];
int i = 0;
//Read Input file
using (StreamReader file = new StreamReader("Score_4.dat"))
{
while ((line = file.ReadLine()) != null && line.Length > 10)
{
line.Trim();
string[] parts;
parts = line.Split(' ');
intArray[0][i] = parts[0];//error: cannot apply indexing
i++;
}
}
Down the road in my code, I intend to make some API calls to a server by constructing a Json object while looping through the array (or alternate object).
Any idea?
Thanks
If you only need the data to be transferred to JSON then you don't need to process the values of the data, just reformat it to JSON arrays.
As you don't know the number of lines in the input file, it is easier to use a List<>, whose capacity expands automatically, to hold the data rather than an array, whose size you would need to know in advance.
I took your sample data and repeated it a few times into a text file and used this program:
static void Main(string[] args)
{
string src = #"C:\temp\Score_4.dat";
List<string> dataFromFile = new List<string>();
using (var sr = new StreamReader(src))
{
while (!sr.EndOfStream)
{
string thisLine = sr.ReadLine();
string[] parts = thisLine.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 3)
{
string jsonArray = "[" + string.Join(",", parts) + "]";
dataFromFile.Add(jsonArray);
}
else
{
/* the line did not have three entries */
/* Maybe keep a count of the lines processed to give an error message to the user */
}
}
}
/* Do something with the data... */
int totalEntries = dataFromFile.Count();
int maxBatchSize = 50;
int nBatches = (int)Math.Ceiling((double)totalEntries / maxBatchSize);
for(int i=0;i<nBatches;i+=1)
{
string thisBatchJsonArray = "{\"myData\":[" + string.Join(",", dataFromFile.Skip(i * maxBatchSize).Take(maxBatchSize)) + "]}";
Console.WriteLine(thisBatchJsonArray);
}
Console.ReadLine();
}
to get this output:
{"myData":[[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1]]}
{"myData":[[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1]]}
It should be easy to adjust the format as required.
I would create a custom Item class and then populate a list, for easy access and sorting, with self contained items. something like:
public Class MyItem
{
public int first { get; set; }
public int second { get; set; }
public float third { get; set; }
public MyItem(int one, int two, float three)
{
this.first = one;
this.second = two;
this.third = three;
}
}
then you could do:
List<MyItem> mylist = new List<MyItem>();
and then in your loop:
using (StreamReader file = new StreamReader("Score_4.dat"))
{
while ((line = file.ReadLine()) != null && line.Length > 10)
{
line.Trim();
string[] parts;
parts = line.Split(' ');
MyItem item = new Item(Int32.Parse(parts[0]),Int32.Parse(parts[1]),Float.Parse(parts[2]));
mylist.Add(item);
i++;
}
}
As there are numbers like 30.1 so int is not suitable for this, and also it must not be a double[] but double[][]:
string[] lines = File.ReadAllLines("file.txt");
double[][] array = lines.Select(x => s.Split(' ').Select(a => double.Parse(a)).ToArray()).ToArray();
Issue is that int array is single dimensional.
My suggestion is that you can put a class with 3 properties and populate a list of class there. It's better to have class with same property names that you require to build JSON. So that you can easily serialize this class to JSON using some nugets like Newtonsoft and make api calls easily.
Your int array is a single dimensional array yet you're trying to index it like a multidemensional array. It should be something like this:
intArray[i] = parts[0]
(However you'll need to handle converting to int for parts that are fractional)
Alternatively, if you want to use a multidimensional array, you have to declare one.
int[][] intArray = new int[*whatever your expected number of records are*][3]
Arrays have a static size. Since you're reading from a file and may not know how many records there are until your file finishes reading, I recommend using something like a List of Tuples or a Dictionary depending on your needs.
A dictionary will allow you to have quick lookup of your records without iterating over them by using a key value pair, so if you wanted your records to match up with their line numbers, you could do something like this:
Dictionary<int, int[]> test = new Dictionary<int, int[]>();
int lineCount = 1;
while ((line = file.ReadLine()) != null && line.Length > 10)
{
int[] intArray = new int[3];
line.Trim();
string[] parts = line.Split(' ');
for (int i = 0; i < 3; i++)
{
intArray[i] = int.Parse(parts[i]);
}
test[lineCount] = intArray;
lineCount++;
}
This will let you access your values by line count like so:
test[3] = *third line of file*

unable to get right output from spliting int arrays

I have goggled and looked various threads at this website and I am still not getting this right.
Objective
Would like to split int arrays in 3 groups
Problem
I am getting an output...
1
4
7
instead of...
[1,2,3]
[4,5,6]
[7,8,9]
1st attempt
static void Main(string[] args)
{
int[] arraya = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Array.Sort(arraya);
int a = 0;
int divideBya = 3;
var resulta = arraya.GroupBy(s => a++ / divideBya).Select(g => g.ToArray()).ToArray();
foreach(var item in resulta)
{
Console.WriteLine("{0}", item[0]);
}
}
2nd attempt
static void Main(string[] args)
{
int u = 0;
int divideByb = 3;
IEnumerable<List<int>> groupedObjects = Enumerable.Range(1, 9).GroupBy(x => u++ / divideByb)
.Select(group => group.ToList()).ToList();
foreach (var item in groupedObjects)
{
Console.WriteLine("{0}", item[0]);
}
}
Can someone point me to the right direction?
Thanks
Your code seems almost correct. Your main problem is your output:
foreach (var item in groupedObjects)
{
Console.WriteLine("{0}", item[0]);
}
You only output the first element of each array. Try this:
foreach (var items in groupedObjects)
Console.WriteLine(string.Join(", ", items));
Try changing your writeline statement to:
Console.WriteLine($"[{item[0]},{item[1]},{item[2]}]");

C#, List Instantiation from existing List?

I'm trying to figure out what is happening in the code snippet below.
In the new list instantiation, it look's like they are referencing the other coins List? I have never seen this before, what is the purpose? Sorry if this has already been answer, if so please redirect me. Thank you for your help.
class Program
{
static void Main(string[] args)
{
List<int> coins = new List<int>();
List<int> amounts = new List<int>() { 1, 5, 10, 25, 50 };
Change(coins, amounts, 0, 0, 51);
Console.ReadKey();
}
static void Change(List<int> coins, List<int> amounts, int highest, int sum, int goal)
{
if (sum == goal)
{
Display(coins, amounts);
return;
}
if (sum > goal)
{
return;
}
foreach (int value in amounts)
{
if (value >= highest)
{
List<int> copy = new List<int>(coins); // <<<<<<<
copy.Add(value);
Change(copy, amounts, value, sum + value, goal);
}
}
}
static void Display(List<int> coins, List<int> amounts)
{
foreach (int amount in amounts)
{
int count = coins.Count(value => value == amount);
Console.WriteLine("{0}: {1}",
amount,
count);
}
Console.WriteLine();
}
}
Here's a description of what the lines do.
List<int> copy = new List<int>(coins); // Creates a new list, initializing the values with the values in coins (creating a copy of coins).
copy.Add(value); // adds additional value to the copy.
From the MSDN documentation https://msdn.microsoft.com/en-us/library/fkbw11z0(v=vs.110).aspx :
List Constructor (IEnumerable)
Initializes a new instance of the List class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
List<int> copy = new List<int>(coins); // They are creating a copy of the list `coins`, called `copy`.

How to get a complete row or column from 2D array in C#

I do not want to use a jagged array and I have a 2D array and I want to get a complete column or row without looping through it. Does anyone have an idea how it can be done.
double [,] array = new double [3,3] ;
1 2 3
4 5 6
Out: 1 2 3 or 2 5
To get a specific row or column from the multidimensional array you can use some LINQ:
public class CustomArray<T>
{
public T[] GetColumn(T[,] matrix, int columnNumber)
{
return Enumerable.Range(0, matrix.GetLength(0))
.Select(x => matrix[x, columnNumber])
.ToArray();
}
public T[] GetRow(T[,] matrix, int rowNumber)
{
return Enumerable.Range(0, matrix.GetLength(1))
.Select(x => matrix[rowNumber, x])
.ToArray();
}
}
You can optimise it for getting rows by using Buffer.BlockCopy(), but to get a column you'll have to loop. Buffer.BlockCopy() ultimately uses a processor instruction to copy a block of memory, so it is pretty fast.
It's convenient to put the code into an extension method to make it easier to call. Note that Buffer.BlockCopy() can only be used on arrays of primitive types, i.e. int, double, char etc. This does NOT include string.
Here's a compilable example:
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApplication4
{
public static class Program
{
private static void Main()
{
var array = new [,]
{
{0.1, 0.2, 0.3, 0.4, 0.5},
{1.1, 1.2, 1.3, 1.4, 1.5},
{2.1, 2.2, 2.3, 2.4, 2.5},
{3.1, 3.2, 3.3, 3.4, 3.5},
};
var row = array.GetRow(2);
// This prints 2.1, 2.2, 2.3, 2.4, 2.5
Console.WriteLine(string.Join(", ", row.Select(element => element.ToString())));
}
}
public static class ArrayExt
{
public static T[] GetRow<T>(this T[,] array, int row)
{
if (!typeof(T).IsPrimitive)
throw new InvalidOperationException("Not supported for managed types.");
if (array == null)
throw new ArgumentNullException("array");
int cols = array.GetUpperBound(1) + 1;
T[] result = new T[cols];
int size;
if (typeof(T) == typeof(bool))
size = 1;
else if (typeof(T) == typeof(char))
size = 2;
else
size = Marshal.SizeOf<T>();
Buffer.BlockCopy(array, row*cols*size, result, 0, cols*size);
return result;
}
}
}
As of March 2021, you can now use the very cool Span2D class for this!
If you are happy using spans (I highly recommend reading about them, they are awesome), you can use the following code
var span2D = new Span2D<double>(array);
//Gets the first row and returns a span of it
var rowSpan = span2D.GetRowSpan(0);
foreach(var number in rowSpan)
{
//Do something with numbers
}
//Gets the 2nd Column as a RefEnumerable and converts it to an array
var column = span2D.GetColumn(1).ToArray();
Here is how i have done it you can use
GetLength(0)
to get the columns and use
GetLength(1)
to get the rows of the 2 Dimensional array and you loop thru it with the for loop if any one else needs this.
string text = "";
for (int i = 0; i < array.GetLength(0); i++)
{
text += Convert.ToString(array[i, 2]) + "\n";
}
an alternative way you can do it is by using a List instead of an array.
Specifically in your case you'd do something like that:
Initially create an inner class that represents a tuple of the array
Create a List of the inner class
Populate the inner class
Get the row that contains something specific
Get the column that contains something specific
public static void Main(string[] args)
{
// #2 -- Instantiate List of myClass
List<myClass> myList = new List<myClass>();
//
// #3 -- Populate the list
myList.Add(new myClass(1,2,3));
myList.Add(new myClass(3,4,5));
myList.Add(new myClass(5,6,6));
//
// #4 -- Get the line where a == 1
myList.Find(x=>x.a == 1);
//
// #5 -- Get column b
myList.Select(x=>x.b);
}
// #1 -- Create the inner class
public class myClass
{
public int a;
public int b;
public int c;
public myClass(int a, int b, int c)
{
this.a =a;
this.b =b;
this.c =c;
}
}
what is needed is a jagged array (not a multidimensional array)
https://msdn.microsoft.com/en-us/library/2s05feca.aspx
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
full example with columns:
using System;
using System.Collections.Generic;
namespace Rextester
{
public class Program
{
public static T[] column<T>(T[][] jaggedArray,int wanted_column)
{
T[] columnArray = new T[jaggedArray.Length];
T[] rowArray;
for(int i=0;i<jaggedArray.Length;i++)
{
rowArray=jaggedArray[i];
if(wanted_column<rowArray.Length)
columnArray[i]=rowArray[wanted_column];
}
return columnArray;
}
public static void Main(string[] args)
{
//Your code goes here
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
Console.WriteLine("Hello, world!");
Console.WriteLine(string.Join(" ",jaggedArray[1]));
Console.WriteLine(string.Join(" ",column(jaggedArray,1)));
}
}
}
similar idea, using extensions:
using System;
using System.Collections.Generic;
namespace Rextester
{
public static class MyExtensions
{
public static string Extend(this Array array)
{
return "Yes, you can extend an array";
}
public static T[] column<T>(this T[,] multidimArray,int wanted_column)
{
int l=multidimArray.GetLength(0);
T[] columnArray = new T[l];
for(int i=0;i<l;i++)
{
columnArray[i]=multidimArray[i,wanted_column];
}
return columnArray;
}
public static T[] row<T>(this T[,] multidimArray,int wanted_row)
{
int l=multidimArray.GetLength(1);
T[] rowArray = new T[l];
for(int i=0;i<l;i++)
{
rowArray[i]=multidimArray[wanted_row,i];
}
return rowArray;
}
}
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
int [,] multidimArray = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
Console.WriteLine(string.Join(" ",multidimArray.column(0)));
Console.WriteLine(string.Join(" ",multidimArray.row(0)));
}
}
}
My use case differs from the question, but is similar. I needed a 2D array of float[2] arrays, that I was using to represent complex numbers.
float[,,] myarray = new float[100,100,2];
float[] result = myarray[1,1]; <-- fails to compile needs all 3 coordinates
The jagged array Simmon mentioned provided the solution.
float[,][] myarray = new float[100,100][];
...
myarray[x,y] = new float[2]; <-- Initialise all elements of jagged 2D array in loop
...
float[] result = [100,100];
if you know the index of the numbers to output..then you don't need to use a loop to get the output desired...
double[,] array = new double[3,3] {{1,2,3}, {4,5,6}, {7,8,9}};
int firstNum = array[0,1];
int secondNum = array[1,1];
this will get 2, 5

Categories