So I ran into a problem, I have a big text in a TXT file and I need to read it into a multidimensional array, without using LINQ.
Example:
Hello(a11) my(a12) friend(a13).
My(a21) name(a22) is(a23) David(a24),
I(a31) am(a32) from(a33) England(a34).
What I have done so far:
String input = File.ReadAllText( "..\\..\\Analize.txt" );
int i = 0, j = 0;
string[,] result = new string[10, 10];
foreach (var row in input.Split('\n'))
{
j = 0;
foreach (var col in row.Trim().Split(' '))
{
result[i, j] = string(col.Trim());
j++;
}
i++;
}
For the others who said his code "works just fine - true if his text is not dynamic size - but if there are more lines then 10, or more words then 10 in this particular example there will be an IndexOutOfRangeException !
If you do know anything about your file this is maybe the best for not running into exceptions:
string[] lines = File.ReadAllLines("C:/temp/test.txt");
int sizex = lines.Length;
int sizey = 1;
for (int i = 0; i < lines.Length; i++)
{
var splitline = lines[i].Split(' ');
sizey = sizey < splitline.Length ? splitline.Length : sizey;
}
String[,] multillines = new string[sizex,sizey];
for (int i = 0; i < lines.Length; i++)
{
var splitline = lines[i].Split(' ');
for (int j = 0; j < splitline.Length; j++)
{
multillines[i, j] = splitline[j];
}
}
Your code as it is works just fine. Not sure what your problem is. But if this:
Hello(a11)
means that this word has to sit on position [1,1] then all you have to change is the counting start from 0 to 1
int i = 1, j = 1;
Try this:
String input ="Hello(a11) my(a12) friend(a13)";
int i = 0, j = 0;
int[,] result = new int[10, 10];
foreach (var row in input.Split(' '))
{
j = 0;
foreach (var col in row.Trim().Split(' '))
{
result[i, j] = int.Parse(col.Trim());
j++;
}
i++;
}
Console.WriteLine(result[3,9]);
Related
I am new to c# and I am trying to print parts of an integer array sorted by multiple threads. For that I use bubble sort inside my function mySort which takes part of the array as a parameter and stores it to a list that I want to display afterwards. The division of the original array is in a loop where I also start the threads. The problem is that the resulting parts are all the same although I pass the different parts of the array to a function to be executed on a thread. The resulting parts includes just numbers of the last part of the original sorted array. I would be glad for any help.
int[] myArray = new int[100];
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = r.Next(0, 100);
}
parts = new List<int[]>();
Thread[] t = new Thread[5];
int[] tmp = new int[myArray.Length/5];
int k = 0;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < tmp.Length; j++)
{
tmp[j] = myArray[k];
k++;
}
Thread myT = new Thread(() => mySort(tmp));
t[i] = myT;
t[i].Start();
}
Function for sorting
static void mySort(int [] arr)
{
for (int i = 0; i < arr.Length - 1; i++)
{
for (int j = 0; j < arr.Length - i - 1; j++)
{
if (arr[j + 1] < arr[j])
{
int tmp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tmp;
}
}
}
parts.Add(arr);
}
EDIT:
By declaring tmp array inside for loop the problem is solved.
for (int i = 0; i < 5; i++)
{
int[] tmp = new int[myArray.Length/5];
for (int j = 0; j < tmp.Length; j++)
{
tmp[j] = myArray[k];
k++;
}
Thread myT = new Thread(() => mySort(tmp));
t[i] = myT;
t[i].Start();
}
this is the text file that i want to split into a 2D array
"YHOO",36.86,21,13873900,37.00
"GOOG",684.11,1114,1821650,686.72
"MSFT",50.54,3993,31910300,50.65
"AAPL",94.40,28201,39817000,94.26
and this is the code I have implemented to do this but it won't work
String input = File.ReadAllText(#"..\..\Data\stockInfo.txt");
int i = 0, j = 0;
string[,] result = new string[3, 5];
foreach (var row in input.Split('\n'))
{
j = 0;
foreach (var col in row.Trim().Split(','))
{
result[i, j] = string.Parse(col.Trim());
j++;
}
i++;
}
Jagged array String[][] (array of array) is often more flexible than 2D one String[,]:
string[][] result = File
.ReadLines(#"..\..\Data\stockInfo.txt")
.Select(line => line.Split(','))
.ToArray();
If you insist on 2D array you have to put less efficient code
string[] lines = File.ReadAllLines(#"..\..\Data\stockInfo.txt");
string[,] result = null;
for (int i = 0; i < lines.Count; ++i) {
string[] items = lines.Split(',');
if (null == result)
result = new string[lines.Count, items.Length];
for (int j = 0; j < items.Length; ++j)
result[i, j] = items[j];
}
The size of array was wrong. Also, you don't need to string.Parse, as output of Split is IEnumerable of strings
int i = 0, j = 0;
string[,] result = new string[4, 5];
foreach (var row in input.Split('\n'))
{
j = 0;
foreach (var col in row.Trim().Split(','))
{
result[i, j] = col.Trim();
j++;
}
i++;
}
I have written the following code but it looks to be far from efficient.
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
}
}
}
//Find position of largest in tempRankingData
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] == largestIntempRankingData)
{
positionLargestIntempRankingData.Add(i + "," + j);
}
}
}
//Find largest in each column
int largestInColumn = 0;
List<string> positionOfLargestInColumn = new List<string>();
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
}
}
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
}
So, I wanted to check about the most efficient way to do this.
Whilst you're finding the largest in each column, you could also be finding the largest overall. You can also capture the positions as you go:
//Find largest in each column
int largestInColumn = 0;
int largestOverall = int.MinValue;
List<string> positionOfLargestInColumn;
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
positionOfLargestInColumn.Add("0," + i);
for (int j = 1; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
positionOfLargestInColumn.Clear();
positionOfLargestInColumn.Add(j + "," + i);
}
else if(tempTankingData[j,i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
if(largestInColumn > largestOverall)
{
positionLargestIntempRankingData.Clear();
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
largestOverall = largestInColumn;
}
else if(largestInColumn == largestOverall)
{
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
}
}
1). You can find largest element and its position in one method and retrieve.
Would be caller of your method concerned about position or actual value, is a matter of concrete case.
2) You can use `yield return' technique in your matrix search (for column based search), so do not compute all column's maximas and push them into the dictionary. Dictionaries are not that fast as arrays, if you can avoid use them, do that.
3) You can keep a matrix in single dimension, long array. Have [] access operator overload, to "emulate" matrix access. Why ? If finding maximum is something frequent you might need to do during program run, having one foreach loop is faster then having 2 nested once. In case of a big matrices, single array search can be easily parallelized among different cores.
If big matrices and/or frequent calls are not your concern, just simplify your code like in points (1), (2).
For your fist two itterations you could replace with this:
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
List<KeyValuePair<double,string>> list = new List<KeyValuePair<double,string>>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
list.Add(new KeyValuePair<double, string>(largestIntempRankingData, i + "," + j)); //Add the value and the position;
}
}
}
//This gives a list of strings in which hold the position of largestInItemRankingData example "3,3"
//Only positions where the key is equal to the largestIntempRankingData;
list.Where(w => w.Key == largestIntempRankingData).ToList().Select(s => s.Value).ToList();
You can get all these pieces of information in a single scan with a little fiddling around. Something like this (converting the rows and columns to a string is trivial and better done at the end anyway):
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
int[] largestColumnRow = new int[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j] = i;
}
}
}
// largestSoFar is the biggest value in the whole matrix
// largestCol and largestRow is the column and row of the largest value in the matrix
// largestPerColumn[j] is the largest value in the jth column
// largestColumnRow[j] is the row of the largest value of the jth column
If you do need to capture all the "maxima" (for want of a better word, because that's not really what you are doing) in a column, you could just change the above code to something like this:
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
List<int>[] largestColumnRow = new List<int>[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j].Add(i);
}
}
}
// Now largestColumnRow[j] gives you a list of all the places where you found a larger
// value for the jth column
I need to create a list of integer arrays. I know ahead of time the length of the arrays, but I don't know how many of them need to be added to the list.
I've tried the following code:
List<int[]> MyListOfArrays = new List<int[]>();
int[] temp = new int[30];
range = xlApp.get_Range("NamedRange");
values = (object[,])range.Value2;
for (int i = 0; i < values.GetLength(0); i++)
{
for (int j = 0; j < values.GetLength(1); j++)
{
temp[j] = Convert.ToInt32(values[i + 1, j + 1]);
}
MyListOfArrays.Add(temp);
}
The temp array is filled just fine. However, MyListOfArrays just ends up with the last iteration of temp repeated for all of the entries. Where am I going wrong?
When you add the temp array to the List, it is just a pointer to the array created on the heap. You need to create a new temp array for every array you add to the list.
List<int[]> MyListOfArrays = new List<int[]>();
range = xlApp.get_Range("NamedRange");
values = (object[,])range.Value2;
for (int i = 0; i < values.GetLength(0); i++)
{
int[] temp = new int[30]; // moved inside the loop
for (int j = 0; j < values.GetLength(1); j++)
{
temp[j] = Convert.ToInt32(values[i + 1, j + 1]);
}
MyListOfArrays.Add(temp);
}
Here's the easiest fix.
Your code:
List<int[]> MyListOfArrays = new List<int[]>();
int[] temp = new int[30];// <-- Move this inside the 'i' for-loop.
range = xlApp.get_Range("NamedRange");
values = (object[,])range.Value2;
for (int i = 0; i < values.GetLength(0); i++)
{
for (int j = 0; j < values.GetLength(1); j++)
{
temp[j] = Convert.ToInt32(values[i + 1, j + 1]);
}
MyListOfArrays.Add(temp);
}
Do this instead:
List<int[]> MyListOfArrays = new List<int[]>();
range = xlApp.get_Range("NamedRange");
values = (object[,])range.Value2;
for (int i = 0; i < values.GetLength(0); i++)
{
int[] temp = new int[30]; //<-- This will create a new array of ints, with each iteration of 1.
for (int j = 0; j < values.GetLength(1); j++)
{
temp[j] = Convert.ToInt32(values[i + 1, j + 1]);
}
MyListOfArrays.Add(temp);
}
You just need to move the line:
int[] temp = new int[30];
immediately after:
for (int i = 0; i < values.GetLength(0); i++) {
so it initializes to a new array at each iteration of the loop.
MyListOfArrays.Add is adding the same reference to you list for each iteration of i, and it overwrites the values in temp[] each time. So you end up with the values of the last iteration repeated.
I have file contain numbers like these
123.4 23.7 89.2 ...
45.8
...
8 columns and 1024 rows, and I want to read this file row by row and put each row in array of double to get the minimum number from this row and put this minimum number in array with size 1024 .
I tried this code in c# ...
static void Main(string[] args)
{
string line;
double[] row = new double[8];
double[] minimum = new double[1024];
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\test.txt");
for (int k = 0; k < 1024; k++)
{
while ((line = file.ReadLine()) != null )
{
string[] numbers = new string[8];
int numCount = 0;
for (int i = 0; i < line.Length; i++)
{
if (line[i] != ' ')
{
numbers[numCount] = "";
while (line[i] != ' ')
{
numbers[numCount] += line[i];
i++;
}
numCount++;
}
}
for (int i = 0; i < 8; i++)
{
row[i] = Convert.ToDouble(numbers[i]);
}
double min = row[0];
for (int j = 0; j < 8; j++)
{
if (row[j] <= min)
min = row[j];
}
minimum[k] = min;
}
}
Console.WriteLine("The array contain:");
for (int i = 0; i < 1024; i++)
Console.WriteLine(minimum[i]);
file.Close();
// Suspend the screen.
Console.ReadLine();
}
There are several methods that can simplify your code - File.ReadLines, String.Split and LINQ Select. Resulting code could look similar to:
var listOfArraysOfDouble = File.ReadLines(fileName)
.Select(row =>
row.Split((string[]) null, StringSplitOptions.RemoveEmptyEntries)
.Select(columnValue => double.Parse(columnValue))
.ToArray()
);