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>>();
Related
I have a multidimensional array that takes lines based on user input like(n lines/4col )
and I have a string of 4 numbers in a line separated by 1 space: 10.00 20.00 30.00 40.00. I need to assign each number to a column in 1 line. The code that I have until now:
int storeNumbers = int.Parse(Console.ReadLine());
string[,] storesemesterProfit = new string[storeNumbers, 4];
for(int m=0; m<storeNumbers; m++)
{
for(int n=0; n < 4; n++)
{
string inputData = Console.ReadLine()
string [] numb = inputData.Split(' ');
storesemesterProfit[m, n] = numb ; // i need help here
You might be looking for
int storeNumbers = int.Parse(Console.ReadLine());
var storesemesterProfit = new decimal[storeNumbers, 4];
for (var m = 0; m < storeNumbers; m++)
{
string inputData = Console.ReadLine();
var numb = inputData.Split(' ');
for (int n = 0; n < Math.Min(4, numb.Length); n++)
storesemesterProfit[m, n] = decimal.Parse(numb[n]);
}
Fair warning. This will likely explode if the user enters some bad data. I suggest taking a look at TryParse Methods
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);
}
}
String list G is :
[0] : {"1,2,5"}
[1] : {"1,2,4,5,6"}
[2] : {"2,4,6"}
[3] : {"1,4,6"}
With the following commands, we conclude that "1,4" exists in the List G[3] :
if (G[i].Contains("1,4")) { //code here }
How to modify the above commands, that in addition feature (Contains), "1,4" exists in the List G[1]?
Program codes
for (int i = 0; i < candid.Count; i++)
{
foreach (TransactionTP b in transactions)
{
string search = candid[i];
var searchNumbers = search.Split(',').Select(int.Parse).ToList();
for (int j = 0; j < G.Count; j++)
{
IEnumerable<int> numbers = G[j].Split(',').Select(int.Parse);
int idx = 0;
foreach (var number in numbers)
{
if (number == searchNumbers[idx])
{
idx++;
}
if (idx == searchNumbers.Count)
{
arraye[i] = arraye[i] + (b.transactionUtility);
break;
}
}
}
}
}
Update:
The order of the searched term matters.
In order to preserve the ordering of the set you are matching go (4,1 in this case), you will need to evaluate each string, keeping track of where you are in the match.
string[] G = new[]
{
"1,2,5",
"1,2,4,5,6",
"2,4,6",
"1,4,6"
};
string search = "1,4";
var searchNumbers = search.Split(',').Select(int.Parse).ToList();
for (int i = 0; i < G.Length; i++)
{
// Convert the string into an enumeration of numbers
IEnumerable<int> numbers = G[i].Split(',').Select(int.Parse);
// Index to keep track of the search
int idx = 0;
// Loop through the input set sequentially
foreach (var number in numbers)
{
// Check if the input matches the next expected number
if (number == searchNumbers[idx])
{
idx++;
}
if (idx == searchNumbers.Count)
{
Console.WriteLine("String {0} matched", G[i]);
break;
}
}
}
Replace your single Contains call with a method that does this:
bool passes = false;
for(int i = 0; i < G.Length; i++)
{
List<string> temp = new List<string>();
if(G[i].Contains(","))
{
temp = G[i].Split(",");
}
else
{
temp = G[i];
}
if(temp.Contains("1") && temp.Contains("4")
{
passes = true;
}
}
return passes;
This eliminates the possibility of matching on "10" or "41" etc etc
It also will not care if your elements are sorted, even though you said they are. It will also match regardless of the number of entries between "1" and "4" in the list.
You could spice this up to take any number of inputs that you want to match before qualifying as a match, I'll leave that to you if you want to make it so.
I would like to create an array of an array from a text file...
There are 20000 line with 21 strings in each line separated by ',' .
I would like to read each line and make it into an array , each line being a new array within.
So I wanted to create the jagged array by starting it like this:
string[][] SqlArray = new string[200000][21];
But it gives: ERROR MESSAGE : Invalid rank specifier: expected ',' or ]
How would I create this array or initialize it?
I will be populating the data in the array like this:
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
for (int i = 0; i < workingArray.Length; i++)
{
for (int k = 0; k < 20; k++)
{
SqlArray[i][k] = workingArray[k];
}
}
}
Thank you
That type of initialization only works in Java. You must declare an array of arrays then initialize each in a loop.
string[][] SqlArray = new string[21][];
for(int index = 0; index < SqlArray.Length; index++)
{
SqlArray[index] = new string[2000000];
}
Alternatively, you can use a non-jagged array. It will probably work for what you need.
string[,] SqlArray = new string[21 , 2000000];
It can be accessed like so:
SqlArray[2,6264] = x;
To anyone who is interested this is how I ended up implementing it:
TextReader readIn = File.OpenText("..\\..\\datafile.txt");
string[][] SqlArray = new string[rowNumCreate][];
int e = 0;
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
SqlArray[e] = new string[valuesInRow +1];
for (int k = 0; k < workingArray.Length; k++)
{
SqlArray[e][k] = workingArray[k];
}
e++;
}
The file being read is a simple mock database set as a flat file that was auto-generated to test an algorithm that I am implementing, which works with jagged arrays; hence instead of working with a data base I just created this for ease of use and to increase and decrease size at will.
Here is the code to build the text file:
Random skill_id;
skill_id = new Random();
// int counter =0;
string seedvalue = TicksToString();
int rowNumCreate = 200000;
int valuesInRow = 20;
string lineInFile = seedvalue;
string delimiter = ",";
for (int i = 0; i < rowNumCreate; i++)
{
for (int t = 0; t < valuesInRow; t++)
{
int skill = skill_id.Next(40);
string SCon = Convert.ToString(skill);
lineInFile += delimiter + SCon;
}
if (rowNumCreate >= i + 1)
{
dataFile.WriteLine(lineInFile);
lineInFile = "";
string userPK = TicksToString();
lineInFile += userPK;
}
}
dataFile.Close();
public static string TicksToString()
{
long ms = DateTime.Now.Second;
long ms2 = DateTime.Now.Millisecond;
Random seeds;
seeds = new Random();
int ran = seeds.GetHashCode();
return string.Format("{0:X}{1:X}{2:X}", ms, ms2, ran).ToLower();
}
I am still a student so not sure if the code is A-grade but it works :)
I've written a code that has a list and I want to sort the list alphabetically and numerically.
For example the first items in the list are
list[0] = "INPUT 10"
list[1] = "INPUT 5".
I want my list reorganized like this:
list[0] = "INPUT 5"
list[1] = "INPUT 10".
So basically my program gets checked items from a checked list box,stores them in a list, and I want it to reorganize the list alphabettically.
The checked list box has items like INPUT 1,INPUT 2,INPUT 3...and so fourth. Can anyone suggest me a way of how to go about this?
UPDATED CODE
I've updated my code and now this code splits the strings into INPUT and 10.The "q" list obtains the checked items in the input box,the string "s" array gets the splittd data from the q list. Then the "numbers" list gets only the number part of the string for example "INPUT 5",the number list will only get "5".Then I want to sort these numbers and build another string combining the sorted number list and the string "INPUT" and add it to the output checkedlistbox. My code isnt working though...any suggestions?It should sort the numbers but it doesnt...anyone have any suggestions of why this code isnt working? And I keep on getting error messages of the array being able to unhandle negative integers and what not.
List<string> q = new List<string>();
List<string> numbers = new List<string>();
private void button_ekle_Click(object sender, EventArgs e)
{
for (int k = clb_input.Items.Count - 1; k >= 0; k--)
{
if (clb_input.GetItemChecked(k) == true)
{
q.Add(clb_input.Items[k].ToString());
//clb_output.Items.Add(clb_input.Items[k]);
clb_input.Items.RemoveAt(k);
}
else { }
}
string[] s = new string[q.Count * 2];
//string[] numbers=new string[q.Count/2];
for (int t = 1; t <= q.Count * 2; t++)
{
if (q != null)
s = q[t - 1].ToString().Split(' ');
else { s[t] = null; }
}
for (int x = 1; x <= q.Count; x++)
{
if (s[2 * x - 1] != null)
{
numbers[x - 1] = s[2 * x - 1];
numbers.Sort();
clb_output.Items.Add("INPUT "+ numbers[x - 1].ToString());
}
else { numbers[x - 1] = null; }
}
}
What you need is Alphanumeric Sorting ( most commonly seen in windows explorer, the way files are sorted)
Code can be found here : http://www.dotnetperls.com/alphanumeric-sorting
Sample
class Program
{
static void Main()
{
string[] highways = new string[]
{
"100F",
"50F",
"SR100",
"SR9"
};
//
// We want to sort a string array called highways in an
// alphanumeric way. Call the static Array.Sort method.
//
Array.Sort(highways, new AlphanumComparatorFast());
//
// Display the results
//
foreach (string h in highways)
{
Console.WriteLine(h);
}
}
}
Output
50F
100F
SR9
SR100
Implementation
public class AlphanumComparatorFast : IComparer
{
public int Compare(object x, object y)
{
string s1 = x as string;
if (s1 == null)
{
return 0;
}
string s2 = y as string;
if (s2 == null)
{
return 0;
}
int len1 = s1.Length;
int len2 = s2.Length;
int marker1 = 0;
int marker2 = 0;
// Walk through two the strings with two markers.
while (marker1 < len1 && marker2 < len2)
{
char ch1 = s1[marker1];
char ch2 = s2[marker2];
// Some buffers we can build up characters in for each chunk.
char[] space1 = new char[len1];
int loc1 = 0;
char[] space2 = new char[len2];
int loc2 = 0;
// Walk through all following characters that are digits or
// characters in BOTH strings starting at the appropriate marker.
// Collect char arrays.
do
{
space1[loc1++] = ch1;
marker1++;
if (marker1 < len1)
{
ch1 = s1[marker1];
}
else
{
break;
}
} while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
do
{
space2[loc2++] = ch2;
marker2++;
if (marker2 < len2)
{
ch2 = s2[marker2];
}
else
{
break;
}
} while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
// If we have collected numbers, compare them numerically.
// Otherwise, if we have strings, compare them alphabetically.
string str1 = new string(space1);
string str2 = new string(space2);
int result;
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
{
int thisNumericChunk = int.Parse(str1);
int thatNumericChunk = int.Parse(str2);
result = thisNumericChunk.CompareTo(thatNumericChunk);
}
else
{
result = str1.CompareTo(str2);
}
if (result != 0)
{
return result;
}
}
return len1 - len2;
}
}
The simplest solution is to just left-pad the numerical values with a space to the same length.
List<string> lst = new List<string>
{
"Item 9",
"Item 999",
"Thing 999",
"Thing 5",
"Thing 1",
"Item 20",
"Item 10",
};
lst.Sort();
Output:
Item 9
Item 10
Item 20
Item 999
Thing 1
Thing 5
Thing 999
And you can always remove the extra white space used for padding after the sorting operation is performed.
You can use Sort with a Comparer like this:
List<string> q = new List<string>();
private void button_ekle_Click(object sender, EventArgs e)
{
for (int k=clb_input.Items.Count-1; k >= 0; k--)
{
if (clb_input.GetItemChecked(k) == true)
{
q.Add(clb_input.Items[k].ToString());
clb_input.Items.RemoveAt(k);
}
else { }
}
q.Sort((p1,p2)=>((int)(p1.split(" ")[1])).CompareTo((int)(p2.split(" ")[1])));
for (int t = 0; t < q.Count; t++)
{
clb_output.Items.Add(q[t].ToString());
}
}