String.Substring behavior when moving a string frame k char places - c#

Inside a For loop I do not understand following behavior of string.Substring(i,j)
having the code
String line = "TTACCTTAAC";
int k = 3; //this is variable but for simplicity is 3
String _pattern = "";
for (int i = 0; i <= line.Length - k; i++) {
_pattern = line.Substring(i, i + k );
//do something...
}
I am expecting the loop to walk over string Line (TACCTTAAC) (from 0 to 10-3 = 7)like:
TTA
ACC
CCT
CTT
TTA
TAA
AAC
However I get
TTA
ACCT
etc...
What am I missing?

Second parameter of Substring is length, not end, so you should just pass k instead of doing your math:
String line = "TTACCTTAAC";
int k = 3; //this is variable but for simplicity is 3
String _pattern = "";
for (int i = 0; i <= line.Length - k; i++) {
_pattern = line.Substring(i, k);
//do something...
}

substring function in c# is used as string.Substring(int startindex, int Length)
so you should use
_pattern = line.Substring(i, k);

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

Generating all variations of certain length out of string

I've seen few implementations of variations of string in C#, but none of them had any limitation on their length. Unfortunately, I cannot modify them to achieve my goal which is e.g.
for:
string = "ABCD" and variationLength = 2
generate new strings:
AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC
I'm looking for exactly this Python's itertools.permutations implementation but in C#. (https://docs.python.org/3/library/itertools.html#itertools.permutations)
Is there anything similar to its in C#? If not, then what is the easiest way to implement it?
Edit_2:
so far I came up with an idea to list all unique chars of given string and then get variations out of them
static void PrintAllKLengthPerm(string str, int k)
{
int n = str.Length;
PrintAllKLengthPermRec(str, "", n, k);
}
// The main recursive method to print all possible strings of length k
static void PrintAllKLengthPermRec(string str, String prefix, int n, int k)
{
// Base case: k is 0, print prefix
if (k == 0)
{
Console.WriteLine(prefix);
return;
}
// One by one add all characters from str and recursively
// call for k equals to k-1
for (int i = 0; i < n; ++i)
{
// Next character of input added
String newPrefix = prefix + str[i];
// k is decreased, because we have added a new character
PrintAllKLengthPermRec(str, newPrefix, n, k - 1);
}
}
static void Main(string[] args)
{
string str = "ABCD";
int permLen = 2;
//get all unique characters in string
string uniqStr = new String(str.Distinct().ToArray());
// Print all possible strings of length permLen out of uniqStr characters
PrintAllKLengthPerm(uniqStr, permLen);
}
However I am looking for more optimal and effective solution
Here's a truly recursive permutation method:
public IEnumerable<string> Permutate(string source, int count)
{
if (source.Length == 1)
{
yield return source;
}
else if (count == 1)
{
for (var n = 0; n < source.Length; n++)
{
yield return source.Substring(n, 1);
}
}
else
{
for (var n = 0; n < source.Length; n++)
foreach (var suffix in Permutate(
source.Substring(0, n)
+ source.Substring(n + 1, source.Length - n - 1), count -1))
{
yield return source.Substring(n, 1) + suffix;
}
}
}
It can be called with Permutate("ABCD", 2) and returns this:
I made the following recursive function which accomplishes your task:
static void Permutations(List<string> output, string str, int n, string curr)
{
if(curr.Length == n)
{
output.Add(curr);
return;
}
foreach(char c in str)
if(!curr.Contains(c.ToString()))
Permutations(output, str, n, curr + c.ToString());
}
and then you call it like this:
string str = "ABCD";
int length = 2;
List<string> perms = new List<string>();
Permutations(perms, str, length, "");
// now the list "perms" will contain the permutations of "str" in length "n"
List<string> newPermutations = new List<string>();
for(int a = 0; a!=inString.Count; a++)
for((int b = 0; b!=inString.Count; b++)
if(noRepetitions && a == b) continue;
newPermutations.Add(""+inString[a] + inString[b]);
I think that that should work; I am still trying to figure out a way to not only have 2 letters.
Edit: Edited it to work, the old one just didn't work... lol
Edit: Thanks to #Bloopy, they helped me spot some errors in my for loops
Here's a solution using modulo and division. There are 4² possible strings of length 2 using the letters ABCD. Number them from 0 to 4²-1 and repeatedly divide each number by 4. Use the resulting remainders as array indexes on the ABCD string.
This has the advantage of allowing you to keep the strings with repeated elements (AA, BB, CC, DD) when needed – just skip the discard step.
string alphabet = "ABCD";
int length = 2;
int[] indexes = new int[length];
char[] item = new char[length];
// loop through all possible strings for the given alphabet and length
for (int i = 0; i < Math.Pow(alphabet.Length, length); i++) {
int dividend = i;
for (int j = length - 1; j >= 0; j--) {
indexes[j] = dividend % alphabet.Length;
dividend /= alphabet.Length;
}
// discard any that use the same alphabet element more than once
if (indexes.Distinct().Count() < length)
continue;
for (int k = 0; k < length; k++) {
item[k] = alphabet[indexes[k]];
}
Console.WriteLine(item);
}
Alternatively, here's a really brief solution using LINQ. Note that this one doesn't work correctly if there are duplicate elements in the string (unless you want to remove the call to Where and keep the AA, BB etc.). I'd need to track the indexes like I did in my method above.
IEnumerable<string> prm = alphabet.Select(c => c.ToString());
for (int a = 1; a < length; a++)
prm = prm.SelectMany(s => alphabet.Where(t => !s.Contains(t)), (x, y) => x + y);
foreach (string s in prm)
Console.WriteLine(s);

Add char to empty string C#

Ive got an empty string s = "";
Ive got a char b = '0';
char b is in a loop so changes after every, I want to keep adding that char b to the string s,
For example, after the first loop string s = "0"
after second round s = "01"
In Java its simple to do that for an empty string with string s += char b;
Couldnt find anything like that on C#, is there an easier way than building a string builder or making a dummy string?
What you describe works in C#:
string x = "";
x += 'Z';
Console.WriteLine(x); // Prints "Z"
Or in a loop:
string x = "";
char b = '#';
for (int i = 0; i < 10; ++i)
{
++b;
x += b;
Console.WriteLine(x); // Prints "A", then "AB", then "ABC" etc.
}
However, you should use StringBuilder for efficiency.
The same loop as above using StringBuilder:
StringBuilder x = new StringBuilder();
char b = '#';
for (int i = 0; i < 10; ++i)
{
++b;
x.Append(b);
Console.WriteLine(x); // Prints "A", then "AB", then "ABC" etc.
}
Easy, but not efficient (String s constantly re-creaing):
char b = '0';
for (int i = 0; i < n; ++i)
s += (Char)(b + i);
Better choice is to use StringBuilder:
char b = '0';
StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; ++i)
sb.Append((Char)(b + i));
s = sb.ToString();

How do I Concat a loop of a char random array?

I have a char array like this:
char[] true_false = new char[2]{'V','F'};
A variable random:
Random rand = new Random();
I have a string called generate_code, with the initial value is true_false[rand.Next(0, 2)].ToString();
string generate_code = true_false[rand.Next(0, 2)].ToString();
And the user will set the int lenght_of;
int lenght_of = int.Parse(Console.ReadLine());
So, what I am trying to do is: the user will define the lenght_of that will be the lenght of the generate_code like this:
for(int i =0; i < lenght_of;i++){
generate_code = generate_code + (char)true_false[rand.Next(0, 2)];
}
But the problem is that I need a fixed variable like :
generate_code = (char)true_false[rand.Next(0, 2)] + (char)true_false[rand.Next(0, 2)];
if lenght_of =2; and I have a loop that will change the generate_code value ten times.How can I do that? **I hope that u guys understand it is hard to explain.
Example:
lenght_of = 2;
//Example "FF";
generate_code = true_false[rand.Next(0, 2)] + true_false[rand.Next(0, 2)];
for(int i =0; i < 10;i++) {
Console.WriteLine(generate_code);
} //Output expected: "FF" "VV" "FV" "VF" "FF"
Your problem is that you're adding two char's together. char is a numeric type.. therefore you're getting numbers as the result. Also, your generate_code assignment must be inside your loop:
for(int i =0; i < 10;i++) {
generate_code = string.Format("{0}", generateCodeWithLength(rand, true_false, lenght_of));
Console.WriteLine(generate_code);
}
Wrap the code generation in a method that accepts the length:
public string generateCodeWithLength(Random rand, char[] true_false, int length) {
var result = new StringBuilder(length);
for (var i = 0; i < length; i++) {
result.Append(true_false[rand.Next(0, 2)]);
}
return result.ToString();
}
Or better yet.. a StringBuilder. Clicky clicky live example.
Alternatively you can also do something like:
for(int i =0; i < 10;i++) {
Console.WriteLine(string.Format("{0}{1}", true_false[rand.Next(0, 2)] + true_false[rand.Next(0, 2)]));
}
You need to refresh generate_code in each iteration of the loop:
for(int i =0; i < 10;i++) {
int loopCounter = 0;
while (loopCounter < length_of)
{
generate_code += true_false[rand.Next(0, 2)]; //Add one more char to generate_code
loopCounter += 1;
}
Console.WriteLine(generate_code);
} //Output expected if length_of = 3: "FFV" "VFV" "FVF" "FFF" "VVV"
That way, each output will be random.

Counting how many times a certain char appears in a string before any other char appears

I have many strings. Each string is prepended with at least 1 $. What is the best way to loop through the chars of each string to count how many $'s there are per string.
eg:
"$hello" - 1
"$$hello" - 2
"$$h$ello" - 2
You could use the Count method
var count = mystring.Count(x => x == '$')
int count = myString.TakeWhile(c => c == '$').Count();
And without LINQ
int count = 0;
while(count < myString.Length && myString[count] == '$') count++;
The simplest approach would be to use LINQ:
var count = text.TakeWhile(c => c == '$').Count();
There are certainly more efficient approaches, but that's probably the simplest.
You could do this, it doesn't require LINQ, but it's not the best way to do it(since you make split the whole string and put it in an array and just pick the length of it, you could better just do a while loop and check every character), but it works.
int count = test.Split('$').Length - 1;
var str ="hello";
str.Where(c => c == 'l').Count() // 2
int count = yourText.Length - yourText.TrimStart('$').Length;
int count = Regex.Matches(myString,"$").Count;
public static int GetHowManyTimeOccurenceCharInString(string text, char c)
{
int count = 0;
foreach(char ch in text)
{
if(ch.Equals(c))
{
count++;
}
}
return count;
}
just a simple answer:
public static int CountChars(string myString, char myChar)
{
int count = 0;
for (int i = 0; i < myString.Length; i++)
{
if (myString[i] == myChar) ++count;
}
return count;
}
Cheers! - Rick
One approach you could take is the following method:
// Counts how many of a certain character occurs in the given string
public static int CharCountInString(char chr, string str)
{
return str.Split(chr).Length-1;
}
As per the parameters this method returns the count of a specific character within a specific string.
This method works by splitting the string into an array by the specified character and then returning the length of that array -1.
//This code worked for me
class CountOfLettersOfString
{
static void Main()
{
Console.WriteLine("Enter string to check count of letters");
string name = Console.ReadLine();
//Method1
char[] testedalphabets = new char[26];
int[] letterCount = new int[26];
int countTestesd = 0;
Console.WriteLine($"Given String is:{name}");
for (int i = 0; i < name.Length - 1; i++)
{
int countChar = 1;
bool isCharTested = false;
for (int j = 0; j < testedalphabets.Length - 1; j++)
{
if (name[i] == testedalphabets[j])
{
isCharTested = true;
break;
}
}
if (!isCharTested)
{
testedalphabets[countTestesd] = name[i];
for (int k = i + 1; k < name.Length - 1; k++)
{
if (name[i] == name[k])
{
countChar++;
}
}
letterCount[countTestesd] = countChar;
countTestesd++;
}
else
{
continue;
}
}
for (int i = 0; i < testedalphabets.Length - 1; i++)
{
if (!char.IsLetter(testedalphabets[i]))
{
continue;
}
Console.WriteLine($"{testedalphabets[i]}-{letterCount[i]}");
}
//Method2
var g = from c in name.ToLower().ToCharArray() // make sure that L and l are the same eg
group c by c into m
select new { Key = m.Key, Count = m.Count() };
foreach (var item in g)
{
Console.WriteLine(string.Format("Character:{0} Appears {1} times", item.Key.ToString(), item.Count));
}
Console.ReadLine();
}
}
This is a similar Solution to find how many email addresses included in a string. This way is more efficient`
int count = 0;
foreach (char c in email.Trim())
if (c == '#') count++;

Categories