How to use two dimensional array - c#

So I have following example:
I have those 3 strings:
string seq3 = "Zeile1: 5,4,2; Zeile2: 9,4,8; Zeile3: 5,3,6";
string seq4 = "Zeile1: 2,5,4,2; Zeile2: 4,1,7,8; Zeile3: 5,3,6,1; Zeile4: 9,2,3,5";
string seq5 = "Zeile1: 2,7,5,4,2; Zeile2: 9,4,1,7,8; Zeile3: 5,3,6,7,1; Zeile4: 9,2,3,5,0; Zeile5: 7,2,5,1,6";
So I need to split the string to become 5 4 2, etc. or 2 5 4 2
And I should output it like matrix.
E.g.:
5 4 2
9 4 8
5 3 6
At the end I need calculate the arithmetic mid value. a + b / 2
So here is my method for spliting, but the dimensions don't work. I Think the method signature is wrong, I should use two dim array.
private static string[,] myArray = new string[5, 5];
public string Berechnen(string s)
{
string result ="";
string[] ZeilenInhalt = s.Split(';');
for (int i = 0; i < 5; i++)
{
string[] daten = ZeilenInhalt[i].Split(':');
string[] ascciizahlen = daten[1].Split(',');
for (int j = 0; j < 5; j++)
{
result = myArray[i, j] = ascciizahlen[j];
}
}
return result;
}
Here is the method for the output
public void Show()
{
for (int i = 0; i < myArray.GetLength(0); i++)
{
for (int j = 0; j < myArray.GetLength(1); j++)
{
Console.Write($"{myArray[i, j]}");
int middle = Convert.ToInt32(myArray[i, j]);
Console.WriteLine($"{middle,1}");
}
}
}
I used interpolate string so I can round it to comma.
The output should be smth like this:
5 4 2
9 4 8
5 3 6
Middle value: 123,2
I have only black screen.
Thanks,

If I understood you correctly, perhaps you could do something like this?
string seq3 = "Zeile1: 5,4,2; Zeile2: 9,4,8; Zeile3: 5,3,6";
string seq4 = "Zeile1: 2,5,4,2; Zeile2: 4,1,7,8; Zeile3: 5,3,6,1; Zeile4: 9,2,3,5";
string seq5 = "Zeile1: 2,7,5,4,2; Zeile2: 9,4,1,7,8; Zeile3: 5,3,6,7,1; Zeile4: 9,2,3,5,0; Zeile5: 7,2,5,1,6";
var resultArray = seq5.Split(';').Select(s => s.Split(':')[1].Trim().Split(',').Select(n => int.Parse(n)).ToArray()).ToArray();
foreach (var subArray in resultArray)
{
foreach (var number in subArray)
{
Console.Write(number);
}
Console.WriteLine($" (line average: {subArray.Average()})");
}
Console.ReadKey();
Is the mid value of each subArray lines that you need ?

Try this method for splitting:
public string[] GetMatrixFromString(string seq)
{
seq = seq.Replace("Zeile", "");
var array = seq.Split(';');
if(array.Length > 0)
{
string[] matrix = new string[array.Length];
for (int i = 0; i < array.Length; i++)
{
var item = array[i];
var matrixLine = item.Split(':')[1].Replace(",", " ");
matrix[i] = matrixLine;
}
return matrix;
}
else
{
return null;
}
}
Be careful to check if return value is null, so that in this case it was not able to parse the string and create matrix.
For example:
string seq3 = "Zeile1: 2,5,4,2; Zeile2: 4,1,7,8; Zeile3: 5,3,6,1; Zeile4: 9,2,3,5";
var matrix = GetMatrixFromString(seq3);
if(matrix == null)
{
Console.WriteLine("Unable to parse input");
}
else
{
foreach (var line in matrix)
{
Console.WriteLine(line);
}
}

Related

I am unable to use substring. How can I fix this?

I am trying to see weather the string is in alphabetical order or no and this error pops up
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at Rextester.Program.Main(String[] args)**
public static void Main(string[] args)
{
string str = "bat\ncat\ndog\n";
int c = 0;
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
c++;
}
}
String[] strArray = new String[c + 1]; //declare with size
int g = 0;
String h = "";
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
strArray[g] = h;
h = "";
g = g + 1;
}
else
{
h = h + str.Substring(i,i + 1);
}
}
String p = "True";
for (int i = 0; i < g; i++)
{
if (i < (g - 1))
{
String f = strArray[i];
String g2 = strArray[i + 1];
char d = f[0];
char s = g2[0];
int d1 = (int)d;
int s1 = (int)s;
if (d1 > s1)
{
p = "False";
}
}
}
Console.WriteLine(p);
}
}
Not sure about what you are doing in your second loop and why is it so complex. We can do the same like this. Hope this helps.
using System;
public class Program
{
public static void Main()
{
string str = "abcd";
str = str.Replace('\n',' ');
String p = "True";
for (int i = 1; i < str.Length; i++) {
// if element at index 'i' is less
// than the element at index 'i-1'
// then the string is not sorted
if (str[i] < str[i - 1]) {
p = "false";
}
}
Console.WriteLine(p);
}
}
Pay attention to the definition of substring
The substring starts at a specified character position and has a
specified length
Considering your first use of substring, here
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, i + 1).Equals("\n"))
{
c++;
}
}
What happens when we get to i=6 here? Substring tries to give you a new string that starts at position i = 6, and is length = 7 characters long. So it tries to give you 7 characters starting from str[6] to str[12]. Well, there is no str[12], so you get an exception.
Its clear that your intent is NOT to get a string that starts at position 6 and is 7 characters long. You want ONE character, so your loop should be this
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, 1).Equals("\n"))
{
c++;
}
}
But theres a much simpler way to get your words in alphabetical order using LINQ
string str = "bat\ncat\ndog\n";
//Removes the trailing \n so you don't have one entry that is only whitespace
str = str.Trim();
string[] strSplit = str.Split('\n').OrderBy(x => x[0]).ToArray();
Now all substrings are sorted alphabetically and you can do whatever you want with them

c# Splitting string to a multi dimensional array?

I encountered a little problem that i can't get my head around.
I have normal string[] array with a text import in it. Every row is stored in separate under every index.
A row usually look something like this:
string[i] = |title1|title2|title3|title4|title5|
string[i+1] = |Word1|Word2|Word3|Word4|Word5|
I want to split these rows and put them in a multi dimensional array.
Already counted how I have to declare the dimensions of the array.
I want to split it now. I was thinking about going through the normal array with two loops and look for the separator while saving the words in a string then copying it to the multi array.
Do you guys have any idea how could i do that, because this is too much hassle for such a small thing.
I want the multi array look something like this:
string[0,0] = title1,
string[0,1] = title2 etc.
string[1,0] = word1
string[1,1] = word2
This is the code that creates the array:
public string [,] SplitArrays(string [] arrayin)
{
long columns = 0;
char line = '|';
string row;
for(int i = 0; i < arrayin.Length;i++)
{
row = arrayin[i];
if (Convert.ToChar(row.Substring(0, 1)) == line)
{
for(int j = 0; j < row.Length;j++)
{
if (Convert.ToChar(row.Substring(j,(j+1))) == line)
{
columns++;
}
}
}
break;
}
int rowlength = arrayin.Length;
string[,] finalarray = new string[columns,rowlength];
And this is how far I got with separating, but I got kind of confuse and I probably messed it up:
int rowcolumncount = 0;
string word = "";
bool next = false;
for(int k = 0; k < arrayin.Length; k++)
{
row = arrayin[k];
for(int l = 0; l < row.Length; l++)
{
if (Convert.ToChar(row[l]) == line)
{
for(int z = 0; next == false;)
{
if(row[z] == line)
{
next = true;
}
else
{
string part = Convert.ToString(row[z]);
word = string.Join("",part);
}
finalarray[l, rowcolumncount] = word;
rowcolumncount++;
}
}
rowcolumncount = 0;
}
}
return finalarray;
}
The main array contains around 12000 lines.
Thank you!
You can try something like this: Split each item with arrayin by | and write these chunks into a line of 2D array:
public string[,] SplitArrays(string[] arrayin) {
if (null == arrayin)
return null;
else if (arrayin.Length <= 0)
return new string[0, 0];
// null : we don't know size (number of columns) before 1st line split
string[,] result = null;
int row = 0;
foreach (var line in arrayin) {
string[] items = line.Split('|');
// - 2 : skip the very first and the very last items which are empty
if (null == result)
result = new string[arrayin.Length, items.Length - 2];
// if line is too short, let's pad result with empty strings
for (int col = 0; col < result.GetLength(1); ++col)
result[row, col] = col + 1 < items.Length - 1
? items[col + 1]
: ""; // padding
row += 1;
}
return result;
}
Usage:
string[] source = new string[] {
"|title1|title2|title3|title4|title5|",
"|Word1|Word2|Word3|Word4|Word5|",
};
// {
// {"title1", "title2", "title3", "title4", "title5"},
// { "Word1", "Word2", "Word3", "Word4", "Word5"}
// }
string[,] array = SplitArrays(source);
If the number of items per line vary, you can use a jagged array.
We create the empty array and set the row count size.
Then we parse all lines of the list and for all line we split it to have desired items to add them into the dimension as we resize the row sub-array.
static public void Test()
{
var list = new string[]
{
"| title1 | title2 | title3 | title4 | title5 |",
"| Word1 | Word2 | Word3 | Word4 | Word5 |"
};
int indexD1 = 0;
string[][] result = null;
Array.Resize(ref result, list.Length);
foreach ( string item in list )
{
var str = item;
str = str.TrimStart('|').TrimStart();
str = str.TrimEnd('|').TrimEnd();
str = str.Replace(" | ", "|");
var items = str.Split('|');
Array.Resize(ref result[indexD1], items.Length);
int indexD2 = 0;
foreach ( string part in items )
result[indexD1][indexD2++] = part;
indexD1++;
}
foreach ( var row in result )
{
foreach ( var str in row )
Console.WriteLine(str);
Console.WriteLine();
}
}
You can also use a List of List of Strings and use the method Add():
var result = new List<List<string>>();

how to read matrix row elements in single line in C# console

I want to read a 5 X 5 matrix from input in console and I want to read row elements in a single line and not in separate lines, like this:
25 16 14 12
10 15 11 10
2 10 9 8 8
7 6 11 20
5 4 1 0 3
Multi line version:
private static int[,] ReadMatrix()
{
var mtr = new int[5, 5];
for (var i = 0; i < 5; i++)
{
var line = Console.ReadLine();
var spl = line.Split(' ');
if (spl.Length != 5) throw new FormatException();
for (var j = 0; j < 5; j++)
mtr[i, j] = int.Parse(spl[j]);
}
return mtr;
}
Single line version:
private static int[,] ReadMatrix()
{
var mtr = new int[5, 5];
var line = Console.ReadLine();
if (string.IsNullOrWhiteSpace(line)) throw new FormatException();
var spl = line.Split(' ');
if (spl.Length != 25) throw new FormatException();
for (var i = 0; i < 25; i++)
mtr[i/5, i%5] = int.Parse(spl[i]);
return mtr;
}
I think this could help: reading two integers in one line using C#
Basicly the string[] tokens = Console.ReadLine().Split(); and then you could call tokens.Length to see how many columns there r going to be.
i used this function to read elements
static int readIndex()
{
string num = string.Empty;
ConsoleKeyInfo cr;
do
{
cr = Console.ReadKey(true);
int n;
if (int.TryParse(cr.KeyChar.ToString(), out n))
{
num += cr.KeyChar.ToString();
Console.Write(cr.KeyChar.ToString());
}
else if (cr.Key == ConsoleKey.Backspace)
{
if (num.Length > 0)
{
Console.Write("\b");
num = num.Remove(num.Length - 1);
}
}
} while (cr.Key != ConsoleKey.Enter);
Console.Write(" ");
return int.Parse(num);
}
then we need just a loop to read elements like this
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
mat[i, j] = (int)readIndex();
}
Console.WriteLine();
}

Removing Leading Zeros in a Char Array

I'm attempting to subtract two strings (of theoretically infinite length) without the use of libraries like BigIntbut I was wondering if anybody has any good ideas on how to remove the leading zeros in the corner cases like the one below?
static void Main(string[] args)
{
Console.WriteLine(Subtract("10", "10005"));
}
static string ReverseInput(string inputString)
{
char[] charArray = inputString.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
static string Subtract(string firstNumInput, string secondNumInput)
{
string firstNum = String.Empty;
string secondNum = String.Empty;
bool negative = false;
// Reverse order of string input
if (firstNumInput.Length > secondNumInput.Length)
{
firstNum = ReverseInput(firstNumInput);
secondNum = ReverseInput(secondNumInput);
}
else if (firstNumInput.Length < secondNumInput.Length)
{
negative = true;
firstNum = ReverseInput(secondNumInput);
secondNum = ReverseInput(firstNumInput);
}
else if (firstNumInput.Length == secondNumInput.Length)
{
// iterate through string to find largest
}
char[] result = new char[firstNum.Length + 1];
int resultLength = 0;
int carry = 0;
for (int i = 0; i < firstNum.Length; i++)
{
int an = (i < firstNum.Length) ? int.Parse(firstNum[i].ToString()) : 0;
int bn = (i < secondNum.Length) ? int.Parse(secondNum[i].ToString()) : 0;
int rn = an - bn - carry;
if (rn < 0)
{
carry = 1;
rn += 10;
}
else
{
carry = 0;
}
result[resultLength++] = (char)(rn + '0');
}
// create the result string from the char array
string finalResult = ReverseInput(new string(result, 0, resultLength));
if (negative)
{
finalResult = '-' + finalResult;
}
return finalResult;
}
Are you looking for TrimStart?
// create the result string from the char array
string finalResult = ReverseInput(new string(result, 0, resultLength)).TrimStart('0');

advance C# string comparison

Is there any class (function) in .Net that can do this:
if
s1 = " I have a black car" and s2 = "I have a car that is small";
int matchingProcentage = matchingFunction(s1,s2);
matchingProcentage == 70% <-- just as an example value :)
Here's a good way of going about it!
Levenshtein Distance
A function like the following should work, it was hastily written so feel free to change things up:
Usage:
GetStringPercentage("I have a black car", "I have a car that is small");
Method:
public static decimal GetStringPercentage(string s1, string s2)
{
decimal matches = 0.0m;
List<string> s1Split = s1.Split(' ').ToList();
List<string> s2Split = s2.Split(' ').ToList();
if (s1Split.Count() > s2Split.Count())
{
foreach (string s in s1Split)
if (s2Split.Any(st => st == s))
matches++;
return (matches / s1Split.Count());
}
else
{
foreach (string s in s2Split)
if (s1Split.Any(st => st == s))
matches++;
return (matches / s2Split.Count());
}
}
you can use Levenshtein Distance algorithm
Using the code found at http://www.dotnetperls.com/levenshtein as a base, I modified it to return a % instead of a number:
public static int Compute(string word1, string word2)
{
int n = word1.Length;
int m = word2.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (word2[j - 1] == word1[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
decimal changesRequired = d[n, m];
//Find the longest word and calculate the percentage equality
if (word1.Length > word2.Length)
return Convert.ToInt32(100 - (changesRequired / word1.Length) * 100);
else
return Convert.ToInt32(100 - (changesRequired / word2.Length) * 100);
}
Hope this helps.
No, there's not. You'd have to implement your own.
Just a suggestion, but would you be able to take both strings and compare character to character and define a percentage based on the number of matching characters?
try this:
public static int MatchingFunction(string s1, string s2, bool duplicate, bool keySensitive)
{
if (!keySensitive)
{
s1 = s1.ToLower();
s2 = s2.ToLower();
}
List<string> ls1 = null;
s2 = s2.Trim();
if (duplicate)
{
ls1 = s1.Trim().Split(' ').ToList();
}
else
{
ls1 = new List<string>();
string[] as1 = s1.Trim().Split(' ');
foreach (string s in as1)
if (!ls1.Contains(s))
ls1.Add(s);
string[] as2 = s2.Trim().Split(' ');
s2 = string.Empty;
foreach (string s in as2)
if (!s2.Contains(s))
s2 = string.Format("{0} {1}", s2, s);
}
int has = 0;
s2 = string.Format("#{0}#", s2.Replace(' ', '#');
foreach (string s in ls1)
has += s2.Contains(string.Format("#{0}#", s)) ? 1 : 0;
return (has * 100 / ls1.Count());
}
string s1 = " I have a black car";
string s2 = "I have a car that is small";
int p = MatchingFunction(s1, s2, false, false);

Categories