I have a char array where I have to remove the elements from the same if I find the certain char. For eg: "paragraphs" is assigned in an char array. I have given search keyword as 'g'. If it is found then I have to remodify the original char array as "raphs" by removing all elements including the found one.
char[] ch = "paragraphs"
search chr = 'g'
Desired result(if chr found):
char[] ch = "raphs"
To explain bit clearer
I have to write a func. to find whether str(user input) contains all the char of the word "abcdef" in the same sequence as specify in the "abcdef". Return True if contains all the char in the same sequence or else false.
User Input: fgajbdcmdgeoplfqz
Output: true
User Input: asrbcyufde
Output: false
You can use LINQ's SkipWhile, which will skip elements until the search character is found.
An additionnal Skip is necessary to obtain raphs instead of graphs, and the ToArray() for the input string and result because you want to work with arrays.
char[] ch = "paragraphs".ToArray();
char search = 'g';
ch = ch.SkipWhile(c => c != search).Skip(1).ToArray(); // raphs
But honestly since your input is a string, I'd work with that:
string ch = "paragraphs";
char search = 'g';
ch = ch.Substring(ch.IndexOf(search) + 1);
and, if really necessary, convert it with .ToArray() afterwards.
And now to answer your 'clarification' (which is pretty much an other question by the way).
There are probably better ways to do it, but here's something that will accomplish what you want in O(n)
private bool ContainsInSequence(string input, string substring)
{
int substringIndex = 0;
for (int i = 0; i < input.Count(); i++)
{
if (input[i] == substring[substringIndex])
{
substringIndex++;
if (substringIndex == substring.Length)
{
return true;
}
}
}
return false;
}
Basically, you go through the input string in order, and each time you encounter the current letter from your substring you move to the next one.
When you reach the end of the substring, you know the input string contained all your substring, so you return true.
If we're not at the end after going through all the input this means there was a letter either out of order or missing, so we return false.
ContainsInSequence("fgajbdcmdgeoplfqz", "abcdef"); // true
ContainsInSequence("asrbcyufde ", "abcdef"); // false
ContainsInSequence("abcdfe", "abcdef"); // false
Try
char[] ch = "paragraphs".ToCharArray();
int index = Array.IndexOf(ch, 'g');
char[] result = new string(ch).Substring(index+1).ToCharArray();
Here's my version without using Linq:
static void Main(string[] args)
{
Console.WriteLine("Please provide a list of characters");
string Charactersinput = Console.ReadLine();
Console.WriteLine("Please provide the search character");
char Searchinput = Console.ReadKey().KeyChar;
Console.WriteLine("");
List<char> ListOfCharacters = new List<char>();
//fill the list of characters with the characters from the string
// Or empty it, if th esearch charcter is found
for (int i = 0; i < Charactersinput .Length; i++)
{
if (Searchinput == Charactersinput[i])
{
ListOfCharacters.Clear();
}
else
ListOfCharacters.Add(Charactersinput [i]);
}
//get your string back together
string Result = String.Concat(ListOfCharacters);
Console.WriteLine("Here's a list of all characters after processing: {0}", Result);
Console.ReadLine();
}
To answer your "clarification" question, which is very different from the original question:
I have to write a func. to find whether str(user input) contains all
the char of the word "abcdef" in the same sequence as specify in the
"abcdef". Return true if contains all the char in the same sequence or
else false.
Input: fgajbdcmdgeoplfqz Output: true
Input: asrbcyufde Output: false
The following function takes in two strings, a source string to search and a string containing the sequence of characters to match. It then searches through the source string, looking for each character (starting at the found position of the previous character). If any character is not found, it returns false. Otherwise it returns true:
public static bool ContainsAllCharactersInSameSequence(string sourceString,
string characterSequence)
{
// Short-circuit argument check
if (sourceString == null) return characterSequence == null;
if (characterSequence == null) return false;
if (characterSequence.Length > sourceString.Length) return false;
if (sourceString == characterSequence) return true;
int startIndex = 0;
foreach (char character in characterSequence)
{
int charIndex = sourceString.IndexOf(character, startIndex);
if (charIndex == -1) return false;
startIndex = charIndex + 1;
}
return true;
}
Related
I want to replace a string (that the user inputs) with the next character in the alphabet. I'm having trouble returning the next value from my loop.
Error message: Index was outside the bounds of the array.
I understand that the array ends, and that might be a problem from the +1 I entered. How would I go about solving this?
string inputString = "abcdefghijklmnopqqrstuvxyz";
char[] inputCharArray = inputString.ToCharArray();
char[] alphabetArray = "abcdefghijklmnopqrstuvxyz".ToArray();
var resultStr = "";
for (int i = 0; i < inputCharArray.Length; i++)
{
if(alphabetArray.Contains(inputCharArray[i]))
resultStr += inputCharArray[i+1];
else
resultStr += inputCharArray[i];
}
System.Console.WriteLine(resultStr);
You're getting an Out Of Range exception because i will eventually equal the last index of your input array, and adding 1 to that number is beyond what the array has.
First, make it easier on yourself by making a function to convert a single char into the next letter.
Note, this answer assumes that you want to "wrap around" - the next letter after "z" goes back to "a".
char NextLetter(char input)
{
if (input < 'a' || input > 'z') // simple validation
throw new ArgumentException();
input += (char)1; // go to the next char value
if (input > 'z') // did you go past z?
input = 'a'; // go back to a
return input;
}
Yes, you can also do modulo, this method is the simple version.
Now you can loop through all the letters in your input to construct the output string. In addition, you don't need to .ToCharArray() a string - a string already implements IEnumerable<char>.
var input = "abcxyz";
var outputBuilder = new StringBuilder();
foreach (char letter in input)
{
outputBuilder.Append(NextLetter(letter));
}
Console.WriteLine(outputBuilder.ToString());
// prints "bcdyza"
You can use Array.IndexOf to find the index of the current character in the alphabet, then you can use the modulo operator (%) to get the index of the next character in the alphabet (assuming the alphabet wraps from z to a in your desired solution):
string inputString = "abcdefghijklmnopqqrstuvxyz";
char[] inputCharArray = inputString.ToCharArray();
char[] alphabetArray = "abcdefghijklmnopqrstuvxyz".ToArray();
var resultStr = "";
for (var i = 0; i < inputCharArray.Length; i++)
{
var indexInAlphabet = Array.IndexOf(alphabetArray, inputCharArray[i]);
var indexOfNextLetter = (indexInAlphabet + 1) % alphabetArray.Length;
resultStr += alphabetArray[indexOfNextLetter];
}
Console.WriteLine(resultStr);
Everyone knows how to replace a character in a string with:
string text = "Hello World!";
text = text.Replace("H","J");
but what I need is to replace multiple characters in a string
something like:
string text = textBox1.Text;
text = text.Replace("a","b")
text = text.Replace("b","a")
now the result is aa , but if the user types ab I want the result to be ba
There's multiple ways to do this.
Using a loop
char[] temp = input.ToCharArray();
for (int index = 0; index < temp.Length; index++)
switch (temp[index])
{
case 'a':
temp[index] = 'b';
break;
case 'b':
temp[index] = 'a';
break;
}
string output = new string(temp);
This will simply copy the string to a character array, fix each character by itself, then convert the array back into a string. No risk of getting any of the characters confused with any of the others.
Using a regular expression
You can exploit this overload of Regex.Replace:
public static string Replace(
string input,
string pattern,
MatchEvaluator evaluator
)
This takes a delegate that will be called for each match, and return the final result. The delegate is responsible for returning what each match should be replaced with.
string output = Regex.Replace(input, ".", ma =>
{
if (ma.Value == "a")
return "b";
if (ma.Value == "b")
return "a";
return ma.Value;
});
For your particular requirement I would suggest you to use like the following:
string input = "abcba";
string outPut=String.Join("",input.ToCharArray()
.Select(x=> x=='a'? x='b':
(x=='b'?x='a':x))
.ToArray());
The output string will be bacab for this particular input
Do not call String.Replace multiple times for the same string! It creates a new string every time (also it has to cycle through the whole string every time) causing memory pressure and processor time waste if used a lot.
What you could do:
Create a new char array with the same length as the input string. Iterate over all chars of the input strings. For every char, check whether it should be replaced. If it should be replaced, write the replacement into the char array you created earlier, otherwise write the original char into that array. Then create a new string using that char array.
string inputString = "aabbccdd";
char[] chars = new char[inputString.Length];
for (int i = 0; i < inputString.Length; i++)
{
if (inputString[i] == 'a')
{
chars[i] = 'b';
}
else if (inputString[i] == 'b')
{
chars[i] = 'a';
}
else
{
chars[i] = inputString[i];
}
}
string outputString = new string(chars);
Consider using a switch when intending to replace a lot of different characters.
Use should use StringBuilder when you are concatenating many strings in a loop like this, so I suggest the following solution:
StringBuilder sb = new StringBuilder(text.Length);
foreach(char c in text)
{
sb.Append(c == 'a' ? 'b' : 'a');
}
var result = sb.ToString();
So I have a string that I need to split by semicolon's
Email address: "one#tw;,.'o"#hotmail.com;"some;thing"#example.com
Both of the email addresses are valid
So I want to have a List<string> of the following:
"one#tw;,.'o"#hotmail.com
"some;thing"#example.com
But the way I am currently splitting the addresses is not working:
var addresses = emailAddressString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim()).ToList();
Because of the multiple ; characters I end up with invalid email addresses.
I have tried a few different ways, even going down working out if the string contains quotes and then finding the index of the ; characters and working it out that way, but it's a real pain.
Does anyone have any better suggestions?
Assuming that double-quotes are not allowed, except for the opening and closing quotes ahead of the "at" sign #, you can use this regular expression to capture e-mail addresses:
((?:[^#"]+|"[^"]*")#[^;]+)(?:;|$)
The idea is to capture either an unquoted [^#"]+ or a quoted "[^"]*" part prior to #, and then capture everything up to semicolon ; or the end anchor $.
Demo of the regex.
var input = "\"one#tw;,.'o\"#hotmail.com;\"some;thing\"#example.com;hello#world";
var mm = Regex.Matches(input, "((?:[^#\"]+|\"[^\"]*\")#[^;]+)(?:;|$)");
foreach (Match m in mm) {
Console.WriteLine(m.Groups[1].Value);
}
This code prints
"one#tw;,.'o"#hotmail.com
"some;thing"#example.com
hello#world
Demo 1.
If you would like to allow escaped double-quotes inside double-quotes, you could use a more complex expression:
((?:(?:[^#\"]|(?<=\\)\")+|\"([^\"]|(?<=\\)\")*\")#[^;]+)(?:;|$)
Everything else remains the same.
Demo 2.
I obviously started writing my anti regex method at around the same time as juharr (Another answer). I thought that since I already have it written I would submit it.
public static IEnumerable<string> SplitEmailsByDelimiter(string input, char delimiter)
{
var startIndex = 0;
var delimiterIndex = 0;
while (delimiterIndex >= 0)
{
delimiterIndex = input.IndexOf(';', startIndex);
string substring = input;
if (delimiterIndex > 0)
{
substring = input.Substring(0, delimiterIndex);
}
if (!substring.Contains("\"") || substring.IndexOf("\"") != substring.LastIndexOf("\""))
{
yield return substring;
input = input.Substring(delimiterIndex + 1);
startIndex = 0;
}
else
{
startIndex = delimiterIndex + 1;
}
}
}
Then the following
var input = "blah#blah.com;\"one#tw;,.'o\"#hotmail.com;\"some;thing\"#example.com;hello#world;asdasd#asd.co.uk;";
foreach (var email in SplitEmailsByDelimiter(input, ';'))
{
Console.WriteLine(email);
}
Would give this output
blah#blah.com
"one#tw;,.'o"#hotmail.com
"some;thing"#example.com
hello#world
asdasd#asd.co.uk
You can also do this without using regular expressions. The following extension method will allow you to specify a delimiter character and a character to begin and end escape sequences. Note it does not validate that all escape sequences are closed.
public static IEnumerable<string> SpecialSplit(
this string str, char delimiter, char beginEndEscape)
{
int beginIndex = 0;
int length = 0;
bool escaped = false;
foreach (char c in str)
{
if (c == beginEndEscape)
{
escaped = !escaped;
}
if (!escaped && c == delimiter)
{
yield return str.Substring(beginIndex, length);
beginIndex += length + 1;
length = 0;
continue;
}
length++;
}
yield return str.Substring(beginIndex, length);
}
Then the following
var input = "\"one#tw;,.'o\"#hotmail.com;\"some;thing\"#example.com;hello#world;\"D;D#blah;blah.com\"";
foreach (var address in input.SpecialSplit(';', '"'))
Console.WriteLine(v);
While give this output
"one#tw;,.'o"#hotmail.com
"some;thing"#example.com
hello#world
"D;D#blah;blah.com"
Here's the version that works with an additional single escape character. It assumes that two consecutive escape characters should become one single escape character and it's escaping both the beginEndEscape charter so it will not trigger the beginning or end of an escape sequence and it also escapes the delimiter. Anything else that comes after the escape character will be left as is with the escape character removed.
public static IEnumerable<string> SpecialSplit(
this string str, char delimiter, char beginEndEscape, char singleEscape)
{
StringBuilder builder = new StringBuilder();
bool escapedSequence = false;
bool previousEscapeChar = false;
foreach (char c in str)
{
if (c == singleEscape && !previousEscapeChar)
{
previousEscapeChar = true;
continue;
}
if (c == beginEndEscape && !previousEscapeChar)
{
escapedSequence = !escapedSequence;
}
if (!escapedSequence && !previousEscapeChar && c == delimiter)
{
yield return builder.ToString();
builder.Clear();
continue;
}
builder.Append(c);
previousEscapeChar = false;
}
yield return builder.ToString();
}
Finally you probably should add null checking for the string that is passed in and note that both will return a sequence with one empty string if you pass in an empty string.
I write this program in c#:
static void Main(string[] args)
{
int i;
string ss = "fc7600109177";
// I want to found (0,91) in ss string
for (i=0; i<= ss.Length; i++)
if (((char)ss[i] == '0') && (((char)ss[i+1] + (char)ss[i+2]) == "91" ))
Console.WriteLine(" found");
}
What's wrong in this program and how can I find (0,91)?
First of all, you don't have to cast to char your ss[i] or others. ss[i] and others are already char.
As a second, you try to concatanate two char (ss[i+1] and ss[i+2]) in your if loop and after you check equality with a string. This is wrong. Change it to;
if ( (ss[i] == '0') && (ss[i + 1] == '9') && (ss[i + 2]) == '1')
Console.WriteLine("found");
As a third, which I think the most important, don't write code like that. You can easly use String.Contains method which does exactly what you want.
Returns a value indicating whether the specified String object occurs
within this string.
string ss = "fc7600109177";
bool found = ss.Contains("091");
Here a DEMO.
use "contain" return only true or false and "index of" return location
of string but I want to find location of "091" in ss and if "091"
repeat like: ss ="763091d44a0914" how can I find second "091" ??
Here how you can find all indexes in your string;
string chars = "091";
string ss = "763091d44a0914";
List<int> indexes = new List<int>();
foreach ( Match match in Regex.Matches(ss, chars) )
{
indexes.Add(match.Index);
}
for (int i = 0; i < indexes.Count; i++)
{
Console.WriteLine("{0}. match in index {1}", i+1, indexes[i]);
}
Output will be;
1. match in index: 3
2. match in index: 10
Here a DEMO.
Use String.Contains() for this purpose
if(ss.Contains("091"))
{
Console.WriteLine(" found");
}
if you want to know where "091" starts in the string then you can use:
var pos = ss.IndexOf("091")
I was just wondering if there is a simple way of doing this. i.e. Replacing the occurrence of consecutive characters with the same character.
For eg: - if my string is "something likeeeee tttthhiiissss" then my final output should be "something like this".
The string can contain special characters too including space.
Can you guys suggest some simple way for doing this.
This should do it:
var regex = new Regex("(.)\\1+");
var str = "something likeeeee!! tttthhiiissss";
Console.WriteLine(regex.Replace(str, "$1")); // something like! this
The regex will match any character (.) and \\1+ will match whatever was captured in the first group.
string myString = "something likeeeee tttthhiiissss";
char prevChar = '';
StringBuilder sb = new StringBuilder();
foreach (char chr in myString)
{
if (chr != prevChar) {
sb.Append(chr);
prevChar = chr;
}
}
How about:
s = new string(s
.Select((x, i) => new { x, i })
.Where(x => x.i == s.Length - 1 || s[x.i + 1] != x.x)
.Select(x => x.x)
.ToArray());
In english, we are creating a new string based on a char[] array. We construct that char[] array by applying a few LINQ operators:
Select: Capture the index i along with the current character x.
Filter out charaters that are not the same as the subsequent character
Select the character x.x back out of the anonymous type x.
Convert back to a char[] array so we can pass to constructor of string.
Console.WriteLine("Enter any string");
string str1, result="", str = Console.ReadLine();
char [] array= str.ToCharArray();
int i=0;
for (i = 0; i < str.Length;i++ )
{
if ((i != (str.Length - 1)))
{ if (array[i] == array[i + 1])
{
str1 = str.Trim(array[i]);
}
else
{
result += array[i];
}
}
else
{
result += array[i];
}
}
Console.WriteLine(result);
In this code the program ;
will read the string as entered from user
2.Convert the string in char Array using string.ToChar()
The loop will run for each character in string
each character stored in that particular position in array will be compared to the character stored in position one greater than that . And if the characters are found same the character stored in that particular array would be trimmed using .ToTrim()
For last character the loop will show error of index out of bound as it would be the last position value of the array. That's why I used * if ((i != (str.Length - 1)))*
6.The characters left after trimming are stored in result in concatenated form .
word = "something likeeeee tttthhiiissss"
re.sub(r"(.)\1+", r"\1",word)