Ignoring whitespace when adding to char array - c#

I'm doing a school exercise where the user inputs a string and the program must check if it's a palindrome. My only problem currently is that I can't get the loop to ignore whitespaces included in the input string.
Console.Write("Insert string: ");
string input = Console.ReadLine();
char[] charArray = new char[input.Length];
for (int i = 0; i < input.Length; i++)
{
if (Char.IsWhiteSpace(input, i))
{
continue;
}
else
{
charArray[i] += input[i];
}
}
string original = new string(charArray);
I've seemingly tried everything I know, but the whitespaces just get added to the array no matter what I try. Is there a simple solution for this?

[EDIT] Ok you can try the replace method which replaces what you provide with what you want instead (space into no space)
string str = "This is a test";
str = str.Replace(" ", "");
MessageBox.Show(str);

How about using the framework and going this route:
char[] charArray = input.Replace(" ", "").ToCharArray();

Maybe this could work ?
Console.Write("Insert string: ");
string input = Console.ReadLine();
char[] charArray = input.Where(character => !Char.IsWhitespace(character)).ToArray();

When a whitespace is encountered, you never update the value at its position and so it remains a whitespace. So, write to a new array/string:
var newString = string.Empty;
for(int i = 0; i < input.Length; i++)
{
if(!Char.IsWhiteSpace(input[i]))
{
newString += input[i];
}
}
or something more like your code:
Console.Write("Insert string: ");
string input = Console.ReadLine();
char[] charArray = new char[input.Length];
var newString = string.Empty;
for (int i = 0; i < input.Length; i++)
{
if (Char.IsWhiteSpace(input, i))
{
continue;
}
else
{
newString += input[i];
}
}
Console.WriteLine(newString);

Related

Take only letters from the string and reverse them

I'm preparing for my interview, faced the problem with the task. The case is that we're having a string:
test12pop90java989python
I need to return new string where words will be reversed and numbers will stay in the same place:
test12pop90java989python ==> tset12pop90avaj989nohtyp
What I started with:
Transferring string to char array
Use for loop + Char.IsNumber
??
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
....
}
}
but currently I'm stuck and don't know how to proceed, any tips how it can be done?
You can't reverse a run of letters until you've observed the entire run; until then, you need to keep track of the pending letters to be reversed and appended to the final output upon encountering a number or the end of the string. By storing these pending characters in a Stack<> they are naturally returned in the reverse order they were added.
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
Stack<char> pending = new Stack<char>();
foreach (char c in input)
if (char.IsNumber(c))
{
// In the reverse order of which they were added, consume
// and append pending characters as long as they are available
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
// Alternatively...
//foreach (char p in pending)
// outputBuilder.Append(p);
//pending.Clear();
outputBuilder.Append(c);
}
else
pending.Push(c);
// Handle pending characters when input does not end with a number
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
return outputBuilder.ToString();
}
A similar but buffer-free way is to do it is to store the index of the start of the current run of letters, then walk back through and append each character when a number is found...
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
int lettersStartIndex = -1;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (char.IsNumber(c))
{
if (lettersStartIndex >= 0)
{
// Iterate backwards from the previous character to the start of the run
for (int j = i - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
lettersStartIndex = -1;
}
outputBuilder.Append(c);
}
else if (lettersStartIndex < 0)
lettersStartIndex = i;
}
// Handle remaining characters when input does not end with a number
if (lettersStartIndex >= 0)
for (int j = input.Length - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
return outputBuilder.ToString();
}
For both implementations, calling Transform() with...
string[] inputs = new string[] {
"test12pop90java989python",
"123test12pop90java989python321",
"This text contains no numbers",
"1a2b3c"
};
for (int i = 0; i < inputs.Length; i++)
{
string input = inputs[i];
string output = Transform(input);
Console.WriteLine($" Input[{i}]: \"{input }\"");
Console.WriteLine($"Output[{i}]: \"{output}\"");
Console.WriteLine();
}
...produces this output...
Input[0]: "test12pop90java989python"
Output[0]: "tset12pop90avaj989nohtyp"
Input[1]: "123test12pop90java989python321"
Output[1]: "123tset12pop90avaj989nohtyp321"
Input[2]: "This text contains no numbers"
Output[2]: "srebmun on sniatnoc txet sihT"
Input[3]: "1a2b3c"
Output[3]: "1a2b3c"
A possible solution using Regex and Linq:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var result = "";
var matchList = Regex.Matches("test12pop90java989python", "([a-zA-Z]*)(\\d*)");
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
foreach (var el in list)
{
if (el.All(char.IsDigit))
{
result += el;
}
else
{
result += new string(el.Reverse().ToArray());
}
}
Console.WriteLine(result);
}
}
I've used code from stackoverflow.com/a/21123574/1037948 to create a list of Regex matches on line 11:
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
Hey you can do something like:
string test = "test12pop90java989python", tempStr = "", finalstr = "";
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
tempStr += charArray[i];
}
else
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
finalstr += charArray[i];
}
}
if(tempStr != "" && tempStr != null)
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
}
I hope this helps

C# - Split at 20 characters but not if it is in between a word

I want to split a string into smaller parts, not exceeding a string length of 20 characters.
The current code is able to split an input string into an array of strings of length 20. However, this could cut a word.
The current code is:
string[] Array;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (i % 20 == 0 && i != 0) {
sb.Append('~');
}
sb.Append(input[i]);
}
Array = sb.ToString().Split('~');
For an input of this: Hello. This is a string. Goodbye., the output would be ['Hello. This is a str', 'ing. Goodbye.'].
However, I don’t want the string to be cut if it’s a word. That word should move to the next string in the array. How can I get the following output instead?
['Hello. This is a', 'string. Goodbye.']
First split your sentence on word-boundary:
var words = myString.Split();
Now concatenate words as long as not more than 20 characters are within your current line:
var lines = new List<string> { words[0] };
var lineNum = 0;
for(int i = 1; i < words.Length; i++)
{
if(lines[lineNum].Length + words[i].Length + 1 <= 20)
lines[lineNum] += " " + words[i];
else
{
lines.Add(words[i]);
lineNum++;
}
}
Here is a fiddle for testing: https://dotnetfiddle.net/s0LrFC
Could be more elegant but this will split the string to lines of a maximum number of characters. The words will be kept together unless they exceed the given length.
public static string[] SplitString(string input, int lineLen)
{
StringBuilder sb = new StringBuilder();
string[] words = input.Split(' ');
string line = string.Empty;
string sp = string.Empty;
foreach (string w in words)
{
string word = w;
while (word != string.Empty)
{
if (line == string.Empty)
{
while (word.Length >= lineLen)
{
sb.Append(word.Substring(0, lineLen) + "~");
word = word.Substring(lineLen);
}
if (word != string.Empty)
line = word;
word = string.Empty;
sp = " ";
}
else if (line.Length + word.Length <= lineLen)
{
line += sp + word;
sp = " ";
word = string.Empty;
}
else
{
sb.Append(line + "~");
line = string.Empty;
sp = string.Empty;
}
}
}
if (line != string.Empty)
sb.Append(line);
return sb.ToString().Split('~');
}
To test:
string[] lines = SplitString("This is a test of the string splitter KGKGKJGKGHKJHJKJKHGJHGhghsjagsjasgajsgjahs yes!", 20);
foreach (string line in lines)
{
Console.WriteLine(line);
}
Output:
This is a test of the
string splitter
KGKGKJGKGHKJHJKJKHGJ
HGhghsjagsjasgajsgja
hs yes!
I believe it's faster to split it only at places where it needs to be, instead of every word. With lines.SelectMany(x => Split(x, 80) can be used with multiline texts:
private static IEnumerable<string> Split(string text, int maxLength)
{
var i = 0;
while (i + maxLength < text.Length)
{
var partIndex = text.LastIndexOf(' ', i + maxLength, maxLength);
if (partIndex == -1)
partIndex = i + maxLength;
yield return text[i..partIndex];
i = partIndex + 1;
}
yield return text[i..];
}

Encoder into Decoding Strings

Using a hand-made code, this is suppose to make the user's input encoded into something different (the letter right after the letter they typed). Whenever I try to run it, the returns are only the user's sentence. I'm happy it works for the decoder, but the encoder needs to encode the message. I'm wondering why it's not working.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EncoderDecoder
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please enter a sentence. No numbers, smybols, or punctuations.");
string sentence = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("Your encoded message.");
string encodedSentence = Encode(sentence);
Console.WriteLine(encodedSentence);
Console.WriteLine("Your decoded message. Also known as your original message.");
string decodedSentence = Decode(sentence);
Console.WriteLine(decodedSentence);
Console.ReadLine();
}
private static string Decode(string encodedSentence)
{
char[] wordArray;
string[] words = encodedSentence.Split(' ');
for (int i = 0; i > words.Length; i++)
{
wordArray = words[i].ToArray();
if (wordArray.Length > 1)
{
char beginLetter = wordArray[0];
wordArray[0] = wordArray[wordArray.Length + 1];
wordArray[wordArray.Length + 1] = beginLetter;
}
for (int t = 0; t < wordArray.Length; t++)
{
wordArray[t] = (char)(wordArray[t] + 1);
}
words[i] = new string(wordArray);
}
string decoded = string.Join(" ", words);
return decoded;
}
private static string Encode(string sentence)
{
char[] wordArray;
string[] words = sentence.Split(' ');
for (int i = 0; i > words.Length; i++)
{
wordArray = words[i].ToArray();
if (wordArray.Length > 1)
{
char beginLetter = wordArray[0];
wordArray[0] = wordArray[wordArray.Length - 1];
wordArray[wordArray.Length - 1] = beginLetter;
}
for(int t = 0; t > wordArray.Length; t++)
{
wordArray[t] = (char)(wordArray[t] + 1);
}
words[i] = new string(wordArray);
}
string encoded = string.Join(" ", words);
return encoded;
}
}
}
Using the arrays, I split the string into the array and then use that array to individually alter the letters. For some reason it's not working...
Both for's are wrong, try: for (int i = 0; i < words.Length; i++)
In the encoder in your for loop you've got where t > word array.length should this be less than

C# Hangman IndexOf Loop

I am a beginner in C# and i am trying to make a "hangman" game. I got stuck at the process when the player guess a letter.
If the word for example is DATA, the application only gets the first A in DATA.
I understand that i have to loop the word to get all the A´s but i am having touble with making it work!
here is my code for the method myGuess:
public void myGuess(String letter)
{
int plats = 0;
string wordToGuess = label4.Text;
plats = wordToGuess.IndexOf(letter);
string wordToShow = label5.Text;
//ersätt "_" med bokstaven på alla positioner bokstaven dyker upp
wordToShow = wordToShow.Substring(0, wordToGuess.IndexOf(letter)) + letter +
wordToShow.Substring(plats + 1, wordToShow.Length - (plats + 1));
label5.Text = wordToShow;
}
I have been trying to google it but because i am a beginner i don't understand the
suggestions people give. Hopefully it is a way to loop for more than one letter with IndexOf?
IndexOf returns the index of the first instance of the character in the string. You could manipulate your string using substring, but you'd be making it more complicated than you need to need. Instead, you can just loop through each of the characters in the String with a for loop:
for (int i = 0; i < wordToGuess.Length; i++ )
{
if (WordToGuess[i] == letter)
{
//Update the correctly guessed letters, (using value of i to determine which letter to make visible.)
}
}
label5.Text = wordToShow;
You can use this:
label4(wordToGuess): DATA
label5(wordToShow): ****
When you call myGuess('A')
label4(wordToGuess): DATA
label5(wordToShow): *A*A
When you call myGuess('T')
label4(wordToGuess): DATA
label5(wordToShow): *ATA
...
public void myGuess(char letter)
{
string wordToGuess = label4.Text;
string wordToShow = label5.Text;
if (wordToShow.Length == 0)
{
for (int i = 0; i < wordToGuess.Length; i++)
wordToShow += "*";
}
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuess[i] == letter || wordToGuess[i] == wordToShow[i])
wordToShow = wordToShow.Remove(i,1).Insert(i, Char.ToString(letter));
}
label5.Text = wordToShow;
}
Here's a long solution that's probably overly generic.
List<int> findIndexes(string myStr, char letter)
{
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
{
if (myStr[i] == letter)
foundIndexes.Add(i);
}
return foundIndexes;
}
string ReplaceIndex(string s, int index, char letter){
return s.Substring(0, index )
+ letter
+ s.Substring(index + 1, s.Length - (index + 1));
}
void Main()
{
string s= "data";
string wordToShow = "____";
var letter = 'a';
var indexes = findIndexes(s, letter);
foreach (var index in indexes)
{
wordToShow = ReplaceIndex(wordToShow, index, letter);
}
Console.WriteLine (wordToShow);
}
A simple for loop should handle it.
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuess[i].ToString().Equals(letter.ToString(), System.StringComparison.InvariantCultureIgnoreCase))
{
wordToShow = string.Format("{0}{1}{2}", wordToShow.Substring(0, i), letter, wordToShow.Substring(i, wordToShow.Length - (i + 1)));
}
}
Here's a fiddle: http://dotnetfiddle.net/UATeVJ

String find and replace

I have a string like
string text="~aaa~bbb~ccc~bbbddd";
The input value will be : bbb
So in the above string i should remove the value "~bbb"
The resulting string should be
text="~aaa~ccc~bbbddd";
I'm not sure what are you wanna do but if i've got it you can do this :
private string ReplaceFirstOccurrence(string Source, string Find, string Replace)
{
int Place = Source.IndexOf(Find);
string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
return result;
}
var result =ReplaceFirstOccurrence(text,"~"+input,"");
One way would be:
string text = "~aaa~bbb~ccc~bbbddd";
string newStr = string.Join("~", text.Split('~').Where(r => r != "bbb"));
But if performance is the consideration then consider some other solution
You can use the regular expression #"\bMYWORDTOREPLACE\b" in c# this would be...
using System.Text.RegularExpressions;
myString = Regex.Replace(myString, #"\bbbb\b", "", RegexOptions.IgnoreCase);
This should do the trick:
string searchValue = "bbb";
text = text.Replace(String.Format("~{0}~", searchValue), "~");
Be sure to search for the ending ~ character as well, otherwise you will also replace part of ~bbbddd.
Like this
string str = "~rajeev~ravi";
string strRemove = "rajeev";
string strNew =str.Replace("~"+strRemove ,"");
public static string Replace(this String str, char[] chars, string replacement)
{
StringBuilder output = new StringBuilder(str.Length);
bool replace = false;
if (chars.Length - 1 < 1)
{
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
replace = false;
// int val = Regex.Matches(ch.ToString(), #"[a-zA-Z]").Count;
for (int j = 0; j < chars.Length; j++)
{
if (chars[j] == c)
{
replace = true;
break;
}
}
if (replace)
output.Append(replacement);
else
output.Append(c);
}
}
else
{
int j = 0;
int truecount = 0;
char c1 = '\0';
for (int k = 0; k < str.Length; k++)
{
c1 = str[k];
if (chars[j] == c1)
{
replace = true;
truecount ++;
}
else
{
truecount = 0;
replace = false;
j = 0;
}
if(truecount>0)
{
j++;
}
if (j > chars.Length-1)
{
j = 0;
}
if (truecount == chars.Length)
{
output.Remove(output.Length - chars.Length+1, chars.Length-1);
// output.Remove(4, 2);
if (replace)
output.Append(replacement);
else
output.Append(c1);
}
else
{
output.Append(c1);
}
}
}
return output.ToString();
}
static void Main(string[] args)
{
Console.WriteLine("Enter a word");
string word = (Console.ReadLine());
Console.WriteLine("Enter a word to find");
string find = (Console.ReadLine());
Console.WriteLine("Enter a word to Replace");
string Rep = (Console.ReadLine());
Console.WriteLine(Replace(word, find.ToCharArray(), Rep));
Console.ReadLine();
}
}
This is an old question, but my solution is to create extension function for string.
Like ".ReplaceFirst" Java method.
You need to create static class like Helper and inside that class create static extension function:
public static class Helpers
{
public static string ReplaceFirst(this String str, string find, string replace)
{
int place = str.IndexOf(find);
if (place < 0)
{
return str;
}
//return str.Substring(0, place) + replace + str.Substring(place + find.Length);
return str.Remove(place, find.Length).Insert(place, replace);
}
}
Usage is same like .Replace method...
string text="~aaa~bbb~ccc~bbbddd";
string temp = text.ReplaceFirst("~bbb", ""); //text="~aaa~ccc~bbbddd"
or more
string text="~aaa~bbb~ccc~bbbddd";
string temp = text.ReplaceFirst("~bbb", "").ReplaceFirst("~bbb", ""); //text="~aaa~cccddd"
Well, you could do something like this.
(You only need to input 'bbb')
string text = "~aaa~bbb~ccc~bbbddd";
string input = "bbb";
string output = text.Replace("~" + input + "~", "~");
Console.WriteLine(output);
Output: ~aaa~ccc~bbbddd

Categories