csharp method that choose every second character from the word - c#

I need a method that returns every other character in a string starting with the first character. For example, a method call with ("Java-language") returns "Jv-agae."
private static void NewMethod(string word)
{
// here comes the code
}

var str = "Java-language";
var xx = new string(str.Where((ch, index) => index % 2 == 0).ToArray());
Console.WriteLine(xx);
Or this one:
var xx = string.Join<char>("", str.Where((ch, index) => (index & 1) == 0));

probably little different then everybody else: :-)
protected static IEnumerable<char> EverySecondChar(string word)
{
for(int i = 0; i < word.Length; i += 2)
yield return word[i];
}
string result = new string(EverySecondChar("Java-language").ToArray());

Here is my suggestion for you:
private string TakeEverySecondChar(string input)
{
var result = string.Empty;
for (int i = 0; i < input.Length; i+=2)
{
result += input.Substring(i, 1);
}
return result;
}

Console.Clear();
string Lang = "Java-language";
string[] LangArr = new string[Lang.Length];
char LangChar;
for (int i = 0; i < Lang.Length; i++)
{
LangChar = Lang[i];
LangArr[i] = LangChar.ToString();
}
for (int i = 0; i < LangArr.Length; i++)
{
Console.Write(LangArr[i]);
i++;
}
Console.ReadLine();

public String strip2ndchar(string text)
{
string final="";
int i = 0;
foreach (char a in text.ToCharArray())
{
if (i % 2 == 0)
final += a;
i++;
}
return final;
}

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

Index Of Longest Run C#

I am trying to solve this question:
Write a function that finds the zero-based index of the longest run in a string. A run is a consecutive sequence of the same character. If there is more than one run with the same length, return the index of the first one.
For example, IndexOfLongestRun("abbcccddddcccbba") should return 6 as the longest run is dddd and it first appears on index 6.
Following what i have done:
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter =1;
int maxCount = 0;
int idenxOf = 0;
for (int i =0; i<array1.Length-1 ; i++)
{
if (comparer.Compare(array1[i],array1[i+1]) == 0)
{
counter++;
}
else {
if(maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
return idenxOf ;
}
}
public class Comparer : IComparer<char>
{
public int Compare(char firstChar, char nextChar)
{
return firstChar.CompareTo(nextChar);
}
}
The problem is that when i get to the last index for example "abbccaaaaaaaaaa"
which is a in this case, and when i=14 (taking this string as example) and when i<array1.Length-1 statment is false, the for loop jumps directrly to return indexOf; and return the wrong index, I am trying to find out how to push the forloop to continue the implementation so idenxOf could be changed to the right index. Any help please?
You could check whether a new best score is achieved for each iteration when current == previous. Minimally slower, but it allows you to write shorter code by omitting an extra check after the loop:
int IndexOfLongestRun(string input)
{
int bestIndex = 0, bestScore = 0, currIndex = 0;
for (var i = 0; i < input.Length; ++i)
{
if (input[i] == input[currIndex])
{
if (bestScore < i - currIndex)
{
bestIndex = currIndex;
bestScore = i - currIndex;
}
}
else
{
currIndex = i;
}
}
return bestIndex;
}
Promote the loop variable i to method scope and repeat the conditional block if (maxCount < counter) { ... } right after the loop exit. Thus, it executes one more time after the loop completes
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter = 1;
int maxCount = 0;
int idenxOf = 0;
int i;
for (i = 0; i < array1.Length - 1; i++)
{
if (comparer.Compare(array1[i], array1[i + 1]) == 0)
{
counter++;
}
else
{
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
return idenxOf;
}
As usual late, but joining the party. A natural classic algorithm:
static int IndexOfLongestRun(string input)
{
int longestRunStart = -1, longestRunLength = 0;
for (int i = 0; i < input.Length; )
{
var runValue = input[i];
int runStart = i;
while (++i < input.Length && input[i] == runValue) { }
int runLength = i - runStart;
if (longestRunLength < runLength)
{
longestRunStart = runStart;
longestRunLength = runLength;
}
}
return longestRunStart;
}
At the end you have both longest run index and length.
public static int IndexOfLongestRun(string str)
{
var longestRunCount = 1;
var longestRunIndex = 0;
var isNew = false;
var dic = new Dictionary<int, int>();
for (var i = 0; i < str.Length - 1; i++)
{
if (str[i] == str[i + 1])
{
if (isNew) longestRunIndex = i;
longestRunCount++;
isNew = false;
}
else
{
isNew = true;
dic.Add(longestRunIndex, longestRunCount);
longestRunIndex = 0;
longestRunCount = 1;
}
}
return dic.OrderByDescending(x => x.Value).First().Key;
}
This will return -1 if the string is empty and you have the flexibility of returning the index and the count depending on your specification.
string myStr = "aaaabbbbccccccccccccdeeeeeeeee";
var longestIndexStart = -1;
var longestCount = 0;
var currentCount = 1;
var currentIndexStart = 0;
for (var idx = 1; idx < myStr.Length; idx++)
{
if (myStr[idx] == myStr[currentIndexStart])
currentCount++;
else
{
if (currentCount > longestCount)
{
longestIndexStart = currentIndexStart;
longestCount = currentCount;
}
currentIndexStart = idx;
currentCount = 1;
}
}
return longestIndexStart;
The accepted answer from Kvam works great for small strings, but as the length approaches 100,000 characters (and perhaps this isn't needed), its efficiency wains.
public static int IndexOfLongestRun(string str)
{
Dictionary<string, int> letterCount = new Dictionary<string, int>();
for (int i = 0; i < str.Length; i++)
{
string c = str.Substring(i, 1);
if (letterCount.ContainsKey(c))
letterCount[c]++;
else
letterCount.Add(c, 1);
}
return letterCount.Values.Max();
}
This solution is twice as fast as Kvam's with large strings. There are, perhaps, other optimizations.

C# printing and skipping a certain number of characters

Ok, here's the problem that I have: using C# I want to format a string by printing out a certain number of characters, then skipping a certain number of characters and then again print, skip.
For example: I want to print 3 characters by skipping the next 2.
So this:
ABCDEFGHIJKL
would become this:
ABCFGHKL
I have only made that it could skip every 2,3,4 and so on characters and I couldn't think of how to approach this further.
Here is so far what I have
string text;
int print = 3;
int skip = 2;
StreamReader file = new StreamReader(#"c:\test.txt");
while ((text = file.Readtext()) != null)
{
string[] stringArray = new string[text.Length];
char ch;
for (int i = 0; i < text.Length; i++)
{
ch = text[i];
stringArray[i] = ch.ToString();
}
for (int i = 0; i < stringArray.Length; i+=skip)
{
Console.Write(stringArray[i]);
}
}
Thanks.
Thank you guys for various great solutions, I really appreciate your help! Thanks!
int take = 3;
int skip = 2;
string s = "ABCDEFGHIJKL";
var newstr = String.Join("", s.Where((c,i) => i % (skip + take) < take));
EDIT
Here are my test results....
int take = 3;
int skip = 2;
string s = String.Join("",Enumerable.Repeat("0123456789", 200));
var t1 = Measure(10000, () => { var newstr = String.Join("", s.Where((c, i) => i % (skip + take) < take)); });
var t2 = Measure(10000, () => { var newstr = new string(s.Where((c, i) => i % (skip + take) < take).ToArray()); });
var t3 = Measure(10000, () => { var newstr = GetString(s, take, skip); });
long Measure(int n,Action action)
{
action(); //JIT???
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++)
{
action();
}
return sw.ElapsedMilliseconds;
}
OUTPUT:
1665 ms. (String.Join)
1154 ms. (new string())
7457 ms. (Sayse's GetString)
EDIT 2
Modifying Sayse's answer as below gives the fastest result among the codes i tested. (311 ms)
public string GetString(string s, int substringLen, int skipCount)
{
StringBuilder newString = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString.Append(s[i++]);
}
}
return newString.ToString();
}
I like I4V's answer more but heres one way to achieve this
public string GetString(string s, int substringLen, int skipCount)
{
string newString = "";
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString += s[i++];
}
}
return newString;
}
Edit Benchmark stated my way was faster
var newStr2 = new Program().GetString(a, take, skip);
var newstr = String.Join("", a.Where((c, i) => i % (skip + take) < take));
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newStr2 = new Program().GetString(a, take, skip);
}
sw.Stop();
Console.WriteLine("my way: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newstr = String.Join("", a.Where((c, iv) => iv % (skip + take) < take));
}
sw.Stop();
Console.WriteLine("I4V way: " + sw.Elapsed.ToString());
Output
my way: 00:00:00.7634927
I4V way: 00:00:01.0183307
int print = 3;
int skip = 2;
Boolean isPrintState = true;
int statePosition = 0;
StringBuilder Sb = new StringBuilder();
using (TextReader reader = new StreamReader(#"c:\test.txt")) {
while (true) {
int Ch = reader.Read();
if (Ch < 0)
break;
statePosition += 1;
if ((isPrintState && (statePosition > print)) || (!isPrintState && (statePosition > skip))) {
statePosition = 1;
isPrintState = !isPrintState;
}
if (isPrintState)
Sb.Append((Char) Ch);
}
}
Console.Write(Sb.ToString());
Amidst so many good looking answer, mine might not be so sophisticated but I thought I would post it anyways. Simple logic.
var take = 3;
var skip = 2;
StringBuilder source = new StringBuilder("ABCDEFGHIJKL");
StringBuilder result = new StringBuilder();
while (source.Length > 0)
{
if (source.Length >= take)
{
result.Append(source.ToString().Substring(0, take));
}
else
{
result.Append(source.ToString());
}
if (source.Length > skip + take)
{
source.Remove(0, skip + take);
}
else
source.Clear();
}
This how to do that.
I think this may be more clear if you are not familiar with Lambda expression
int print = 3;
int skip = 2;
string str = "ABCDEFGHILKL";
StringBuilder stringBuilder = new StringBuilder();
string res = String.Empty;
int i = 0;
while (i < str.Length)
{
stringBuilder.Append(str.Substring(i, Math.Min(print, str.Length - i)));
i += print + skip;
}
Console.WriteLine(stringBuilder.ToString());

.NET C# Logic Function, recurrent function

I have some string in format like that
XXXX-XXXX-X_X_
All "_" should be replaced with Letters and numberst to prodce sth like that:
XXXX-XXXX-XAXA
XXXX-XXXX-XAXB
XXXX-XXXX-XAXC
XXXX-XXXX-XAXD
XXXX-XXXX-XAXE
XXXX-XXXX-XAXF
XXXX-XXXX-XAXG
(...)
XXXX-XXXX-XZX8
XXXX-XXXX-XZX9
XXXX-XXXX-X0XA
(...)
XXXX-XXXX-X2XA
XXXX-XXXX-X2XB
I know hoe to make it with one "_".
string alphaLetters = "ABCDEFGHIJKLMNOPQRSTUWXYZ0123456789ABCDEF";
foreach (char letter in alphaLetters.ToCharArray())
{
Numbers.Add(number.Replace('_', letter)));
}
I want this code to be working with unknown number of "_".
Can you help?
IMHO it must be recursive. (Note: that does not mean it must use recursive method call, although I used recursive call in the following code, it can be easily converted to internal recursion stack. )
public static void RunSnippet()
{
var r = new List<string>();
Replace("asd_asd_asd_".ToCharArray(), 0, r);
foreach(var s in r) { Console.WriteLine(s); }
}
public static char[] possibilities = new char[] { 'A', 'B', 'C' };
public static void Replace(char[] chars, int startIndex, IList<string> result)
{
for (int i = startIndex; i < chars.Length; i++)
{
if (chars[i] != '_')
{
continue;
}
// we found first '_'
for (int j = 0; j < possibilities.Length; j++)
{
chars[i] = possibilities[j];
Replace(chars, i + 1, result);
}
chars[i] = '_'; // take back what we replaced
return; //we're done here
}
// we didn't find any '_', so all were replaced and we have result:
result.Add(new string(chars));
}
Try this one:
var alphaIndexes = new List<int>();
string alphaLetters = "ABCDEFGHIJKLMNOPQRSTUWXYZ0123456789ABCDEF";
for(int n = 0; n<Numbers.Count; n++) {
char[] numberLetters = Numbers[n].ToCharArray();
int position = 0;
for(int i = numberLetters.Length - 1; i>=0; i--) {
if(numberLetters[i] == '_') {
int alphaIndex = 0;
if(alphaIndexes.Count <= position)
alphaIndexes.Add(0);
else {
alphaIndex = alphaIndexes[position];
}
numberLetters[i] = alphaLetters[alphaIndex];
position++;
}
}
if(alphaIndexes.Count > 0) {
alphaIndexes[0]++;
for(int j = 0; j < alphaIndexes.Count; j++) {
if(alphaIndexes[j] >= alphaLetters.Length) {
alphaIndexes[j] = 0;
if (j < alphaIndexes.Count)
alphaIndexes[j+1]++;
}
}
}
Numbers[n] = new String(numberLetters);
Numbers[n].Dump();
}

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