Replacing value before space? - c#

I want to replace only the value before space
for example:
1. 1 3
2. 23 5
3. 650 300
4. 1350 19
would be:
1. 2 3
2. 55 5
3. 950 300
4. 5602 19
I only need to change the value before space... after space should remain same. Every value is in a separate row. Before space value can be 1 to 4 digits and after space value can be 1 to 3 digits.
string num = "650 3";
string afterspace = num.Substring(0, 4);
Console.WriteLine(afterspace);
string beforespace = num.Substring(4);
Console.WriteLine(beforespace);

If this is a space separated string, you can try the bewlo approach..
var arr = str.Split(' ');
arr[0] = newValue;//here you can use the index and new value to assign the new value.
str = string.Join(" ",arr);

Related

Comparing 2 strings c#

So I have a string which I split in half. Now I need to compare both parts of the string and output has to be all the elements that are the same in both of them.
I noticed some people using Intersect, but I don't know why it doesn't work for me, I get really weird output if I use it.
So here is my code:
string first= "1 3 6 8 4 11 34 23 3 1 7 22 24 8"
int firstLength = first.Length;
int half = firstLength / 2;
string S1 = first.Substring(0, half);
string S2= first.Substring(half, half);
var areInCommon = S1.Intersect(S2);
Console.WriteLine("Numbers that these 2 strings have in common are: ");
foreach (int i in areInCommon)
Console.WriteLine(i);
So in this case output would be: 1, 3 and 8.
Any help would be appreciated.
You were close what you really want is arrays of the numbers not arrays of chars... you can get that with the split function.
string first= "1 3 6 8 4 11 34 23 3 1 7 22 24 8"
int firstLength = first.Length;
int half = firstLength / 2;
string S1 = first.Substring(0, half);
string S2= first.Substring(half, half);
var areInCommon = S1.Split(" ".ToArray()).Intersect(S2.Split(" ".ToArray());
Console.WriteLine("Numbers that these 2 strings have in common are: ");
foreach (var i in areInCommon)
Console.WriteLine(i);
A note about using ToArray():
I use ToArray() out of habit and the reason is that if you want to pass in parameters you can't do it without this construct. For example if the data looked like this:
string first= "1, 3, 6, 8, 4, 11, 34, 23, 3, 1, 7, 22, 24, 8"
then we would need to use
.Split(" ,".ToArray(), StringSplitOptions.RemoveEmptyEntries);
since this happens a lot, I use the .ToArray() out of habit. You can also use a new construct (eg new char [] { ' ', ',' } ) I find that more cumbersome, but probably slightly faster.
simply split both the string within an array and them compare both the strings using contains() function.
string implements IEnumerable<char>, thus, you're intersecting sequences of characters instead of strings.
You should use String.Split:
IEnumerable<string> S1 = first.Substring(0, half).Split(' ');
IEnumerable<string> S2= first.Substring(half, half).Split(' ');
And then your intersection will output the desired result.
Also, you can convert each string representation of numbers into integers (i.e. int):
IEnumerable<int> S1 = first.Substring(0, half).Split(' ').Select(s => int.Parse(s));
IEnumerable<int> S2 = first.Substring(half, half).Split(' ').Select(s => int.Parse(s));
You are converting all your characters into integers. The character '1' is not represented by the integer 1. Change your foreach to:
foreach (char i in areInCommon)

Convert a string to multidimensional array

I have a matrix, which is read from the console. The elements are separated by spaces and new lines. How can I convert it into a multidimensional int array in c#? I have tried:
String[][] matrix = (Console.ReadLine()).Split( '\n' ).Select( t => t.Split( ' ' ) ).ToArray();
but when I click enter, the program ends and it doesn't allow me to enter more lines.
The example is:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
int[,] Matrix = new int[n_rows,n_columns];
for(int i=0;i<n_rows;i++){
String input=Console.ReadLine();
String[] inputs=input.Split(' ');
for(int j=0;j<n_columns;j++){
Matrix[i,j]=Convert.ToInt32(inputs[j]);
}
}
you can try this to load the matrix
First things first, Console.ReadLine() reads a single line from the input. So in order to accept multiple lines you need to do 2 things:
Have a loop which allows the user to continue entering lines of data. You could let them go until they leave a line blank, or you could fix it to 5 lines of input
Store these "lines" of data for future processing.
Assuming the user can enter any number of lines, and a blank line (just hitting enter) indicates the end of data entry something like this will suffice
List<string> inputs = new List<string>();
var endInput = false;
while(!endInput)
{
var currentInput = Console.ReadLine();
if(String.IsNullOrWhitespace(currentInput))
{
endInput = true;
}
else
{
inputs.Add(currentInput);
}
}
// when code continues here you have all the user's input in separate entries in "inputs"
Now for turning that into an array of arrays:
var result = inputs.Select(i => i.Split(' ').ToArray()).ToArray();
That will give you an array of arrays of strings (which is what your example had). If you wanted these to be integers you could parse them as you go:
var result = inputs.Select(i => i.Split(' ').Select(v => int.Parse(v)).ToArray()).ToArray();
// incoming single-string matrix:
String input = #"1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9";
// processing:
String[][] result = input
// Divide in to rows by \n or \r (but remove empty entries)
.Split(new[]{ '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
// no divide each row into columns based on spaces
.Select(x => x.Split(new[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries))
// case from IEnumerable<String[]> to String[][]
.ToArray();
result:
String[][] result = new string[]{
new string[]{ "1","2","3","4","5" },
new string[]{ "2","3","4","5","6" },
new string[]{ "3","4","5","6","7" },
new string[]{ "4","5","6","7","8" },
new string[]{ "5","6","7","8","9" }
};
It can be done in multiple ways
You can read a single line containing multiple numbers separated by a char, split by that char obtaining an array of ints and then you should fetch a matrix.
With out-of-the-box linq there is no trivial way for the fetching step and i think it is not really the case to use third-party libraries from codeplex like LinqLib or something.

How to identify proper substring length

I'm trying to read column values from this file starting at the arrow position:
Here's my error:
I'm guessing it's because the length values are wrong.
Say I have column with value :"Dog "
with the word dog and a few spaces after it. Do I have to set the length parameter as 3 (for dog) or can I set it as 6 to accommodate the spaces after Dog. This because each column length is fixed. As you can see some words are smaller than others and in order to be consistent I just want to set length as max column length (ex: 28 is length of 3rd column of my file but not all 28 spots are taken up everytime - ex: the word client is only 6 characters long
Robert Levy's answer is correct for the issue you're seeing - you've attempted to pull a substring from a string with a starting position that is greater than the length of the string.
You're parsing a fixed-length field file, where each field has a certain amount of characters, whether or not it uses all of them, and the pos and len arrays are intended to define those field lengths for use with Substring. As long as the line you're reading matches the expected field starts and lengths, you will be ok. As soon as you come to a line that doesn't match (for example, what appears to be the totals line - 0TotalRecords: 3,390,315) the field length definitions you've been using won't work, as the format has changed (and the line length may not even be the same).
There are a couple of things I would change to make this work. First, I would change your pos and len arrays so that they take the entirety of the field, not part of it. You can use Trim() to get rid of any leading or trailing blanks. As defined, your first field will only take the last number of the Seq# (pos 4, len 1), and your second field will only take the first 5 characters of the field, even though it appears to have space for ~12 characters.
Take a look at this (it's hard to be exact working from the picture, but for purposes of demonstration it will work):
1 2 3 4
01234567890123456789012345678901234567890
Seq# Field Description
3 BELNR ACCOUNTING DOCUMENT NBR
The numbers are the position of each charcter in the line. I would define the pos array to be the start of the field (0 for the first field, and then the position of the first letter of the field heading for each field after that), so you would have:
Seq# = 0
Field = 6
Description = 18
The len array would hold the length of the field, which I would define as the amount of characters up to the beginning of the next field, like this:
Seq# = 6
Field = 12
Description = 28 (using what you have as it is hard to tell
This would make your array initialization the following:
int[] pos = new int[3] { 0, 6, 18 };
int[] len = new int[3] { 6, 12, 28 };
If you wanted the fourth field, it would start at position 36 (pos 18 + len 28 = 36).
The second thing is I would check in the loop to see if the Total Records line is there, and skip that line (most likely it's the last line):
foreach (string line in textBox1.Lines)
{
if (!line.Contains("Total Records"))
{
val[j] = line.Substring(pos[j], len[j]).Trim();
}
}
Another way to do this would be to modify the original query and add a TakeWhile clause to it to only take lines until you hit the Total Records one:
string[] lines = File.ReadAllLines(ofd.FileName).Skip(8)
.TakeWhile(l => !l.Contains("Total Records")).ToArray();
The above would skip the first 8 lines and take all the remaining lines up to, but not including, the first line to contain "Total Records" in the string.
Then you could do something like this:
string[] lines = File.ReadAllLines(ofd.FileName).Skip(8)
.TakeWhile(l => !l.Contains("Total Records")).ToArray();
textBox1.Lines = lines;
int[] vale = new int[3];
int[] pos = new int[3] { 0, 6, 18 };
int[] len = new int[3] { 6, 12, 28 };
foreach (string line in textBox1.Lines)
{
val[j] = line.Substring(pos[j], len[j]).Trim();
}
Now you don't have to check for the "Total Records" line.
Of course, if there are other lines in your file, or there are records after the "Total Records" line (which I rather doubt) you'll have to handle those cases as well.
In short, the code for pulling out the substrings will only work for lines that match that particular format (or more specifically, have fields that match those positions/lengths) - anything outside out of that will either give you incorrect values or throw an error (if the start position is greater than the length of the string).
that exception is complaining about the first parameter which suggests that your file contains a row that is < 18 characters

Math Probability with C# - How to get the enumerated value of 3 different characters at a certain try

Hi I have asked this question yesterday and was closed of being not understood, so I'll try to be more specific as I can this time. So here's the situation.
1. I have 3 characters: A, B, C in a character array like the following :
char[] characters = {'A', 'B', 'C'};
2. when enumerating all possible matches of these 3 characters I get for example the following:
Text = A
tries = 1
indexes = characters[0]
------------
Text = B
tries = 2
indexes = characters[1]
------------
Text = C
tries = 3
indexes = characters[2]
------------
Text = AA
tries = 4
indexes = characters[0] characters[0]
------------
Text = AB
tries = 5
indexes = characters[0] characters[1]
------------
Text = AC
tries = 6
indexes = characters[0] characters[2]
------------
Text = BA
tries = 7
indexes = characters[1] characters[0]
------------
Text = BB
tries = 8
indexes = characters[1] characters[1]
------------
Text = BC
tries = 9
indexes = characters[1] characters[2]
------------
Text = CA
tries = 10
indexes = characters[2] characters[0]
------------
Text = CB
tries = 11
indexes = characters[2] characters[1]
------------
Text = CC
tries = 12
indexes = characters[2] characters[2]
3. Now given the number of certain try, can we get the number of indexes at this specific try? Meaning for example at the try number 10 at this try the Text was CA (as shown above) because the indexes was characters[2] & characters[0], So is there a Math equation to know these indexes numbers having the number of try?
Thank you
can we get the number of indexes at this specific try
For any given number of letters, you are just counting numbers in base-3. So simply convert from decimal to base-3, and back again.
To determine how many possibilities there are for lesser string-lengths: there are 3^n different possible strings of length n that use 3 letters.
If the value of try is less than 4:
characters[try-1]
Otherwise:
characters[(try-4)/3], characters[(try-4)%3]
where % is the modulus operator and / is integer division
So for try == 10 you get:
characters[2], characters[1]
Note: as your try values start from 1 and the indices start from 0, we need a -1 right from the start
Note: due to the way the modulus operation works, the second index could have also been written as (try-1)%3

Best way to Find which cell of string array contins text

I have a block of text that im taking from a Gedcom (Here and Here) File
The text is flat and basically broken into "nodes"
I am splitting each node on the \r char and thus subdividing it into each of its parts( amount of "lines" can vary)
I know the 0 address will always be the ID but after that everything can be anywhere so i want to test each Cell of the array to see if it contains the correct tag for me to proccess
an example of what two nodes would look like
0 #ind23815# INDI <<<<<<<<<<<<<<<<<<< Start of node 1
1 NAME Lawrence /Hucstepe/
2 DISPLAY Lawrence Hucstepe
2 GIVN Lawrence
2 SURN Hucstepe
1 POSITION -850,-210
2 BOUNDARY_RECT (-887,-177),(-813,-257)
1 SEX M
1 BIRT
2 DATE 1521
1 DEAT Y
2 DATE 1559
1 NOTE * Born: Abt 1521, Kent, England
2 CONT * Marriage: Jane Pope 17 Aug 1546, Kent, England
2 CONT * Died: Bef 1559, Kent, England
2 CONT
1 FAMS #fam08318#
0 #ind23816# INDI <<<<<<<<<<<<<<<<<<<<<<< Start of Node 2
1 NAME Jane /Pope/
2 DISPLAY Jane Pope
2 GIVN Jane
2 SURN Pope
1 POSITION -750,-210
2 BOUNDARY_RECT (-787,-177),(-713,-257)
1 SEX F
1 BIRT
2 DATE 1525
1 DEAT Y
2 DATE 1609
1 NOTE * Born: Abt 1525, Tenterden, Kent, England
2 CONT * Marriage: Lawrence Hucstepe 17 Aug 1546, Kent, England
2 CONT * Died: 23 Oct 1609
2 CONT
1 FAMS #fam08318#
0 #ind23817# INDI <<<<<<<<<<< start of Node 3
So a when im done i have an array that looks like
address , string
0 = "1 NAME Lawrence /Hucstepe/"
1 = "2 DISPLAY Lawrence Hucstepe"
2 = "2 GIVN Lawrence"
3 = "2 SURN Hucstepe"
4 = "1 POSITION -850,-210"
5 = "2 BOUNDARY_RECT (-887,-177),(-813,-257)"
6 = "1 SEX M"
7 = "1 BIRT "
8 = "1 FAMS #fam08318#"
So my question is what is the best way to search the above array to see which Cell has the SEX tag or the NAME Tag or the FAMS Tag
this is the code i have
private int FindIndexinArray(string[] Arr, string search)
{
int Val = -1;
for (int i = 0; i < Arr.Length; i++)
{
if (Arr[i].Contains(search))
{
Val = i;
}
}
return Val;
}
But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1
Like so
if (FindIndexinArray(SubNode, "1 BIRT ") != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim();
}
sorry this is a longer post but hopefully you guys will have some expert advice
Can use the static method FindAll of the Array class:
It will return the string itself though, if that works..
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, item => item.Contains("Sex") || item.Contains("Drugs") || item.Contains("Computer"));
The => indicates a lamda expression. Basically a method without a concrete implementation.
You can also do this if the lamda gives you the creeps.
//Declare a method
private bool HasTag(string s)
{
return s.Contains("Sex") || s.Contains("Drugs") || s.Contains("Computer");
}
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, HasTag);
What about a simple regular expression?
^(\d)\s=\s\"\d\s(SEX|BIRT|FAMS){1}.*$
First group captures the address, second group the tag.
Also, it might be quicker to dump all array items into a string and do your regex on the whole lot at once.
"But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1"
Copy the returned value to a variable before you test to prevent multiple calls.
IndexResults = FindIndexinArray(SubNode, "1 BIRT ")
if (IndexResults != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[IndexResults].Replace("2 DATE ", "").Trim();
}
The for loop in method FindIndexinArray shd break once you find a match if you are interested in only the first match.

Categories

Resources