Formatting into a Matrix form - c#

I try using the code they have on msdn: it uses foreach and that puts each element on a different line.
How would I put it into a 3x3 matrix format?
char[] delimiterChars = { ' ', ',', '.', ':', '\t' ,'[' ,']', ';', '"', 'A', '=' };
string text = "A = [5 4 1; 3 6 1; 2 3 9]";
System.Console.WriteLine("Original text: '{0}'", text);
string[] words = text.Split(delimiterChars);
System.Console.WriteLine("{0} words in text:", words.Length);
foreach (string element in words)
{
System.Console.WriteLine(element);
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
Thanks in advance!

There are at least two ways to do that.
1.
At first your example will output
17 words in text:
This is because when you split string by all of the specified chars you get many empty strings, to get rid of them add StringSplitOptions.RemoveEmptyEntries option to Split method.
string[] words = text.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
Now you will get
9 words in text:
You can get 3 x 3 matrix with simple for loop, like
string[,] matrix = new string[3, 3];
for (int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
matrix[i, j] = words[i * 3 + j];
}
}
However you need to know number of rows and columns (or assume that the matrix is square).
The method will look something like this
public static string[,] GetMatrix1(string text, int n, int m)
{
char[] delimiterChars = { ' ', ',', '.', ':', '\t' ,'[' ,']', ';', '"', 'A', '=' };
string[] words = text.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
string[,] matrix = new string[n, m];
for (int i = 0; i < n; ++i)
{
for(int j = 0; j < m; ++j)
{
matrix[i, j] = words[i * m + j];
}
}
return matrix;
}
2.
Another way is to split text by [ and ] first, then by ; to get rows and at last by (space) to get elements in each row.
char[] delimiter1 = { '[', ']' };
char[] delimiter2 = { ';' };
char[] delimiter3 = { ' ' };
string[][] words = text.Split(delimiter1)[1]
.Split(delimiter2, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split(delimiter3, StringSplitOptions.RemoveEmptyEntries))
.ToArray();
There you will get string[][], number of columns may vary for each row, but if you want string[,] type you need to convert it.
As the result the implementation will be like this one
public static string[,] GetMatrix2(string text)
{
char[] delimiter1 = { '[', ']' };
char[] delimiter2 = { ';' };
char[] delimiter3 = { ' ' };
string[][] words = text.Split(delimiter1)[1]
.Split(delimiter2, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split(delimiter3, StringSplitOptions.RemoveEmptyEntries))
.ToArray();
string[,] matrix = new string[words.Length, words[0].Length];
for(int i = 0; i < words.Length; ++i)
{
for(int j = 0; j < words[i].Length; ++j)
{
matrix[i, j] = words[i][j];
}
}
return matrix;
}

Related

C# ReadFile _ Method returns string that sliced into jagged array

I need to implement a method according to conditions:
char[][] Foo(StreamReader stream, int arraySize) {}
Method should return an underlying string that sliced into jagged array of characters according to arraySize.
First condition. If stream is string.Empty and arraySize is 10:
return Array.Empty<char[]>();
Second condition. If stream is "Lorem" and arraySize is 5:
return new char[][]
{
new char[] { 'L', 'o', 'r', 'e', 'm' },
};
Third condition. If stream is "Lorem" and arraySize is 1:
return new char[][]
{
new char[] { 'L' },
new char[] { 'o' },
new char[] { 'r' },
new char[] { 'e' },
new char[] { 'm' },
};
Forth condition. If stream is "Loremipsumdolorsitamet" and arraySize is 5:
return new char[][]
{
new char[] { 'L', 'o', 'r', 'e', 'm' },
new char[] { 'i', 'p', 's', 'u', 'm' },
new char[] { 'd', 'o', 'l', 'o', 'r' },
new char[] { 's', 'i', 't', 'a', 'm' },
new char[] { 'e', 't' },
};
With my solution doesn't works Forth condition; To test my function I've created temp.txt file alongside Program.cs and put there above mentiond values (Lorem, Loremipsumdolorsitamet).
Implementation:
char[][] Foo(StreamReader stream, int arraySize)
{
long arrLength = 0;
if (streamReader.BaseStream.Length % arraySize == 0)
{
arrLength = streamReader.BaseStream.Length / arraySize;
}
else
{
arrLength = streamReader.BaseStream.Length / arraySize + 1;
}
char[][] array = new char[arrLength][];
for (int i = 0; i < array.Length; i++)
{
array[i] = new char[arraySize];
for (int j = 0; j < arraySize; j++)
{
array[i][j] = (char)streamReader.Read();
}
}
return array;
}
call function and test results:
int num = 5;
var myArray = Foo(new StreamReader(#"D:\temp.txt"), num);
for (int i = 0; i < myArray.Length; i++)
{
for (int k = 0; k < myArray[i].Length; k++)
{
Console.Write(myArray[i][k] + "\t");
}
Console.WriteLine();
}
Resalt is:
L o r e m
i p s u m
d o l o r
s i t a m
e t ▒ ▒ ▒
So, last array length is 5 (but should be - 2) and what the symbol is: '▒' ?
Please help!
I've fixed my error:
char[][] Foo(StreamReader stream, int arraySize)
{
long arrLength;
if (stream.BaseStream.Length % arraySize == 0)
{
arrLength = stream.BaseStream.Length / arraySize;
}
else
{
arrLength = (stream.BaseStream.Length / arraySize) + 1;
}
char[][] array = new char[arrLength][];
for (int i = 0; i < array.Length; i++)
{
long chunkSize = arraySize;
if (i == array.Length - 1 && stream.BaseStream.Length % arraySize != 0)
{
chunkSize = stream.BaseStream.Length % arraySize;
}
array[i] = new char[chunkSize];
for (int j = 0; j < chunkSize; j++)
{
array[i][j] = (char)stream.Read();
}
}
return array;
}
If you are on .NET6, you can make use of the Chunk method to split the input into chunks:
char[][] Foo(TextReader stream, int arraySize)
{
return stream.ReadToEnd().Chunk(arraySize).ToArray();
}
If this is not possible, you may calculate the size of the current chunk as Math.Min(arraySize, array.Length - i * arraySize) and use this instead of arraySize in your for (int i...) loop. (array.Length - i * arraySize is the remaining length):
for (int i = 0; i < array.Length; i++)
{
int chunkSize = Math.Min(arraySize, streamReader.BaseStream.Length - i * arraySize);
array[i] = new char[chunkSize];
for (int j = 0; j < chunkSize; j++)
{
array[i][j] = (char)streamReader.Read();
}
}
This might not be the best way, but for simplicity's sake you can just make a List<char[]> and then use StreamReader.ReadBlock() to fill a buffer.
Then, based on the number of characters read in that block (conveniently returned as an int by the .ReadBlock() method), you instantiate an array of the correct size and add it to the list, using .ToArray() at the end to produce your char[][].
char[][] Foo(StreamReader streamReader, int arraySize)
{
List<char[]> listOfArrays = new List<char[]>();
char[] charBuffer = new char[arraySize];
int charactersInThisBlock;
while (!streamReader.EndOfStream)
{
//fills the charBuffer with as many characters as possible up to its' limit (arraySize)
//the second parameter (0) simply keeps the function reading from the last unread character
//the output will tell you the number of characters read into the buffer
charactersInThisBlock = streamReader.ReadBlock(charBuffer, 0, arraySize);
//create/fill your new array, and add it to the list
char[] newArray = new char[charactersInThisBlock];
for(int i = 0; i < charactersInThisBlock; i++)
{
newArray[i] = charBuffer[i];
}
listOfArrays.Add(newArray);
}
//return char[][]
return listOfArrays.ToArray();
}

How to make couple of different lists using c#?

Got a quite huge problem. My task is to split the input text into sentences,then to split sentences into words. Here comes the code :
using System.Collections.Generic;
using System.Linq;
namespace TextAnalysis
{
static class SentencesParserTask
{
public static List<List<string>> ParseSentences(string text)
{
var sentencesList = new List<List<string>>();
var splittedText = text.Split('.', '!', '?', ';', ':', '(', ')');
List<string>[] mas = new List<string>[splittedText.Length];
for (int i = 0; i < splittedText.Length; i++)
{
mas[i] = new List<string>();
}
for (int j = 0; j < splittedText.Length; j++)
{
mas[j]= GetWordsOutOfTheSentence(splittedText);
bool isEmpty = !(mas[j]).Any();
if(!isEmpty)
sentencesList.Add(mas[j]);
}
return sentencesList;
}
private static List<string> GetWordsOutOfTheSentence(string[] splittedText)
{
var wordList = new List<string>();
foreach (var sentence in splittedText)
{
var wordsArray = sentence.Split('^', '#', '$', '-', '+', '1', '=', ' ', '\t', '\n', '\r',',');
for (int i = 0; i < wordsArray.Length; i++)
{
if (wordsArray[i] != string.Empty)
{
var fineWord = wordsArray[i];
wordList.Add(fineWord.ToLower());
}
}
}
return wordList;
}
}
}
The main problem is on test 1)
Failed : TextAnalysis.SentencesParser_Tests.CorrectlyParse_SentenceDelimiters
Input text: [a.b!c?d:e;f(g)h;i]
Sentence #0 is wrong
Expected is <System.Collections.Generic.List<System.String>> with 1 elements, actual is <System.Collections.Generic.List<System.String>> with 9 elements
Values differ at index [1]
Extra: < "b", "c", "d"... >
My code just continue adding new words in list and then add that lists in main list.What should i do?
As stated in one of the comments, you are passing the entire splittedText variable into GetWordsOutOfTheSentence and not just that sentence. This means you are passing the list of 9 sentences instead of one sentence. As suggested in the comments your code should pass the specific sentence instead.
public static List<List<string>> ParseSentences(string text)
{
var sentencesList = new List<List<string>>();
var splittedText = text.Split('.', '!', '?', ';', ':', '(', ')');
List<string>[] mas = new List<string>[splittedText.Length];
for (int i = 0; i < splittedText.Length; i++)
{
mas[i] = new List<string>();
}
for (int j = 0; j < splittedText.Length; j++)
{
//Passes entire splittedText:
mas[j]= GetWordsOutOfTheSentence(splittedText);
//Passes just the relevant sentence
mas[j]= GetWordsOutOfTheSentence(splittedText[j]);
bool isEmpty = !(mas[j]).Any();
if(!isEmpty)
sentencesList.Add(mas[j]);
}
return sentencesList;
}
Actually i just used additional list to solve the problem. Thanks everybody,it was awesome!
using System.Collections.Generic;
using System.Linq;
namespace TextAnalysis
{
static class SentencesParserTask
{
public static List<List<string>> ParseSentences(string text)
{
var sentencesList = new List<List<string>>();
var splittedText = text.Split('.', '!', '?', ';', ':', '(', ')');
foreach (var sentence in splittedText)
{
var wordsArray = sentence.Split('^', '#', '$', '-', '+', '1', '=', ' ', '\t', '\n', '\r', ',');
var additionalMainList = new List<string>();
var wordList = new List<string>();
foreach (var word in wordsArray)
{
if (word != string.Empty)
{
var fineWord = word;
wordList.Add(fineWord.ToLower());
additionalMainList.Add(fineWord.ToLower());
}
}
bool isEmpty = !(wordList).Any();
if (!isEmpty)
sentencesList.Add(additionalMainList);
wordList.Clear();
}
return sentencesList;
}
}
}

split String[] with seperators and convert it to 2D Array

There is is a problem in my c# code.
I have a string array with 23 values in each line, seperated by a semicolon.
I want to split each value and parse it into an 2D [double] Array that should look like:
[(number of lines),22].
The string array looks like:
[0]
0,00;111,00;0,00;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,10;-0,10;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00
[1]
0,00;120,00;0,00;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,10;-0,10;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00
The double array should look like:
[0,0] 0,00
[0,1] 111,00
[0,2] 0,00
[0,3] -1,00
and so on.
Do you have any ideas?
This is my current Code, that does not work.
double[,] values = new double[z, 22];
char[] seperator = { ';' };
int x = 0;
for (int i = 0; i < z; i++) {
for (int j = 0; j < 22; j++) {
values[i, j] = Data[x].Split(seperator);
x++;
}
}
How you could achieve this:
I use decimal here if you use double it will get the result 0 from a string like 0,00. So you can use double but if it can it will shorten it. Whit decimal a string like 0,00 will be 0.00
string[] arr = new string[] { "0,00;111,00;0,00;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,10;-0,10;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00" , "0,00;120,00;0,00;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,10;-0,10;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00" };
// array conaining decimals
decimal[,] numbers = new decimal[2,23];
// loop thrue strings in arr
for (int i = 0; i < arr.Length; i++)
{
// split that string by ';'
string[] numberStrings = arr[i].Split(';');
// loop thrue the result of the splitted strings
for (int j = 0; j < numberStrings.Length; j++)
{
// parse that number from splitted string to decimal an put it on his place in the 2d array
numbers[i, j] = decimal.Parse(numberStrings[j]);
}
}
Please, try this code.
String a1 = "0,00;111,00;0,00;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,00;0,10;-0,10;-1,00;-1,00;0,00;0,00;0,00;0,00;0,00";
// new array split string by ';'
String[] arr1 = a1.Split(';');
int count = 0;
Console.WriteLine("\n\n\n-----------\nType 1 (only 1 array) \n-----------\n\n\n");
while ( count <= arr1.Length -1){
Console.WriteLine(arr1[count].ToString());
count++;
}
Console.WriteLine("\n\n\n-----------\nType 2 (multidimensional array) \n-----------\n\n\n");
// new array split string by ';' and ','
String[] arr2 = a1.Split(';');
string[,] arrFinal = new string[23,2];
// re-start counter
count = 0;
while (count <= arr2.Length - 1)
{
arrFinal[count, 0] = arr2[count].ToString().Split(',')[0];
arrFinal[count, 1] = arr2[count].ToString().Split(',')[1];
Console.WriteLine(arr2[count].ToString());
Console.WriteLine("item ({0},{1}) = {2} | item ({3},{4}) = {5} ", count, "0", arrFinal[count, 0], count, "1", arrFinal[count, 1], arrFinal[count, 1] );
count++;
}

convert Text file 2D array to integer 2D array

I am trying to use data from text file (matrix [i, j]). I have code works with one dimension array but doesn't work with two dimension array. I tried to use different method but I always get an error.
string fileContent = File.ReadAllText(file path);
string[] integerStrings = fileContent.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
integers = new int[integerStrings.Length];
for (int n = 0; n < integerStrings.Length; n++)
integers[n] = int.Parse(integerStrings[n]);
I modify it to this
string fileContent = File.ReadAllText(path);
string[,] integerStrings = fileContent.Split(new char[,] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
integers = new int[integerStrings.Length,2];
for (int n = 0; n < integerStrings.Length; n++)
for (int j = 0; j <2; n++)
integers[n,j] = int.Parse(integerStrings[n,j]);
the text file
0 0
2 0
4 0
6 0
8 1
10 1
12 1
14 2
16 3
18 3
Note the code I need should be fixable with rows number
get the lines from the file then split each line to get your 2d array. Here is a rough first draft. You can test and refactor to improve on it if needed.
int[,] matrix = null;
int rowCount = 0;
int colCount = 0;
var lines = File.ReadAllLines(path);
rowCount = lines.Length;
for(int i = 0; i < rowCount; i++) {
var line = lines[i];
var tokens = line.Split(new []{' ', '\t'}, StringSplitOptions.RemoveEmptyEntries);
if(matrix == null) {
colCount = tokens.Length;
matrix = new int[rowCount, colCount];
}
for(int j = 0; j < colCount; j++) {
matrix[i, j] = int.Parse(tokens[j]);
}
}
this part is for display the matrix
int rowLength = matrix.GetLength(0);
int colLength = matrix.Rank;
for (int i = 0; i < rowLength; i++) {
for (int j = 0; j < colLength; j++) {
Console.Write(string.Format("{0} ", matrix[i, j]));
}
Console.WriteLine();
Console.WriteLine();
}
Console.ReadLine();
If you want 2d array split method just gives 1d array so you have to split twice...
First split by line breaks then by spaces...
string[] rows = fileContent.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int[,] result = new int[rows.Length,2];
for(int i = 0; i < rows.Length; i++)
{
var col = rows[i].Split(new char{' ','\t'}, StringSplitOptions.RemoveEmptyEntries);
result[i,0] = int.Parse(col[0]);
result[i,1] = int.Parse(col[1]);
}

Read rows/columns of numbers in a text file (c#)

I have a text file with the following numbers for example:
1 2 3
4 5 6
How do I read each individual number into an array?
It needs to move along each row so read in 1, 2 and then 3 into a array of then move to the second row and read 4 5 and 6.. and show the number of cells in a textbox.
this is my code, but I got an error.
List<string> list2 = new List<string>();
for (int i = 0; i < lines.Length; i++)
{
char[] chars = lines[i].ToCharArray();
for (int j = 0; j < chars.Length; j++)
{
if (!Char.IsWhiteSpace(chars[j]))
list2.Add(chars[j].ToString());
}
}
You could convert it to a jagged int array:
int[][] result = text
.Split('\n')
.Select(line =>
line
.Split(' ')
.Select(numberText => int.Parse(numberText))
.ToArray()).ToArray();
Iterate through like this:
foreach (int[] line in result)
{
Console.WriteLine(string.Join(", ", line)); // or iterate through its numbers again
// or whatever you want to do
}
Edit
List<string> list2 = new List<string>();
string path = "xy"; //your path
string[] lines = File.ReadAllLines(path);
int[][] result = lines
.Select(line =>
line
.Split(' ')
.Select(numberText => int.Parse(numberText))
.ToArray()).ToArray();
foreach (int[] line in result)
{
list2.Add(string.Join(", ", line)); // or whatever format you want the text to be
}
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
label3.Text = openFileDialog1.FileName;
textBox1.Text = File.ReadAllText(label3.Text);
FileStream fs = File.OpenRead(label3.Text);
string[] lines = new StreamReader(fs).ReadToEnd().Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
fs.Close();
List<string> list2 = new List<string>();
for (int i = 0; i < lines.Length; i++)
{
char[] chars = lines[i].ToCharArray();
for (int j = 0; j < chars.Length; j++)
{
if (!Char.IsWhiteSpace(chars[j]))
list2.Add(chars[j].ToString());
}
}
}

Categories