Remove all characters after the last letter - c#

The following simple program will find the last letter in a string that a user enters and then remove everything after that point. So, if a person enters one string.... everything after the g should be removed. I've got the following as a little program:
class Program
{
static void Main(string[] args)
{
Console.Write("Enter in the value of the string: ");
List<char> charList = Console.ReadLine().Trim().ToList();
int x = charList.LastIndexOf(charList.Last(char.IsLetter)) ;
Console.WriteLine("this is the last letter {0}", x);
Console.WriteLine("This is the length of the string {0}", charList.Count);
Console.WriteLine("We should have the last {0} characters removed", charList.Count - x);
for (int i = x; i < charList.Count; i++)
{
charList.Remove(charList[i]);
}
foreach (char c in charList)
{
Console.Write(c);
}
Console.ReadLine();
}
}
I've tried numerous variations of this and none of them getting it exactly write. This particular program with an input of string.... the output of the program is strin.. So somehow it's leaving on what it should be taking away and it's actually taking away letters that it shouldn't. Can anyone give an indication as to why this is happening? The desired output, again should be string.

Try this:
string input = Console.ReadLine(); // ABC.ABC.
int index = input.Select((c, i) => new { c, i })
.Where(x => char.IsLetter(x.c))
.Max(x => x.i);
string trimmedInput = input.Substring(0, index + 1);
Console.WriteLine(trimmedInput); // ABC.ABC

Jsut for the explanation, that's because each time you remove a character, you increment the i counter but also decrementing charList.Count so you're actually removing 1 character, leaving the next one, then removing again and so on...
For example, with the input "string...." and x being 5 (index of the G letter) you're doing :
1st iteration :
Remove the g char so x becomes 6 and charList.Count becomes 9 (10-1)
Next iteration :
Remove the char at index 6 which is now the second . (your string being "strin....").
So you missed the first point.
I let you check other answers as they contains more elegant solutions for your problems.

I think it would be a lot more straight forward to simply Substring the string the user entered. So consider the following modified code:
class Program
{
static void Main(string[] args)
{
Console.Write("Enter in the value of the string: ");
var s = Console.ReadLine().Trim();
List<char> charList = s.ToList();
int x = charList.LastIndexOf(charList.Last(char.IsLetter)) ;
Console.WriteLine("this is the last letter {0}", x);
Console.WriteLine("This is the length of the string {0}", charList.Count);
Console.WriteLine("We should have the last {0} characters removed", charList.Count - x);
Console.WriteLine(s.Substring(0, x + 1);
Console.ReadLine();
}
}
here we store the value the user entered into s, find the last index of a letter, and then Substring through that letter when writing out to the console.

string s = console.ReadLine();
s = s.Substring(0, s.ToList().FindLastIndex(char.IsLetter) + 1);

You also can use a function of string called SubString, to get everything from the first to the last letter index.

Here's a pretty inefficient way to do it (just for fun!)
var trimmedInput = string.Join("", input.Reverse().SkipWhile(x => !char.IsLetter(x)).Reverse());

You could use this extension:
public static string TrimLettersLeft(this string input)
{
int lastLetterIndex = -1;
for (int i = input.Length - 1; i >= 0; i--)
{
if (Char.IsLetter(input[i]))
{
lastLetterIndex = i;
break;
}
}
if( lastLetterIndex == -1)
return input;
else
return input.Substring(0, lastLetterIndex + 1);
}
Input: test...abc...
Output: test...abc
DEMO

Solution will be like this.
string charList = "string..."; //any string place here
int x = charList.LastIndexOf(charList.Last(char.IsLetter));
String str = charList.ToString().Substring(0, x + 1);

This will match every word character (A-Z, 0-9 and _):
string Input = Console.ReadLine();
string Userinput = String.Empty;
Regex TextSearch = new Regex(#"\w*");
if(TextSearch.IsMatch(Input))
Userinput = TextSearch.Match(Input).Groups[0].Value;
else
// No valid Input

What I believe would be the shortest, simplest option:
Edit: A comment pointed out an initial error here, so I added a little fix. Should work nicely now (might not be the optimal solution, but I thought it was a fun an simple solution anyway):
var userInput = Console.ReadLine();
Console.WriteLine(new string(userInput.Reverse()
.SkipWhile(c => !char.IsLetter(c))
.Reverse()
.ToArray()));

Related

Find index locations of a specified letter in a string

My apologies if I didn't explain it clear the first time. I have edited my explanation further in bold below.
In the program below user enters a word and then enters a letter which the user would like to replace with any character. For instance, user enter's a word "Hello" and the replacement letter is "l" with "$". So "Hello" will become "He$$o". First, the goal is to find the location of "l" (example - 2,3) and then replace the element in that specific location.
I started by finding the location of "l" and storing it in a findIndex array. Every time I run the program I get "22222" stored in findIndex[] array. At this point, I am not even sure if I am even applying the right logic. Any advice will be appreciated! Please don't use LINQ.
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
int[] findIndex = new int[myString.Length];
for (int i = 0; i < myString.Length; i++)
{
findIndex[i] = myString.IndexOf(myCharacter, 0);
}
for (int i = 0; i < findIndex.Length; i++)
{
Console.Write(findIndex[i]);
}
}
This is probably what you want :
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
List<int> findIndex = new List<int>();
int offs = 0;
while (offs < myString.Length)
{
offs = myString.IndexOf(myCharacter, offs);;
if (offs == -1)
break;
findIndex.Add(offs);
offs++;
}
for (int i = 0; i < findIndex.Count; i++)
{
Console.Write(findIndex[i]);
}
}
Set an initial offset to the start of the string, try to find index of required character if not found exit, otherwise store the location & increment the offset so the next loop starts after the found position. Then keep looping.
As you do not know how many characters will be found, then a list is better than an array to store the results. It can always be converted to an array with .ToArray() afterwards.
Below should serve the purpose :
var str = "Hello";
var replaced = str.Replace('l', '$');
Even though it's easier to use String.Replace, I just want to give you an explanation why you are getting [2,2,2,2,2] array.
Firstly, IndexOf method returns index of character's first occurence, starting from 0.
Secondly, you are using method overload IndexOf(myCharacter, 0) which "says" that character search should be done always from the start of the string.
To circumvent the issue, you should use IndexOf(myCharacter, i, 1) instead to set the search to start from i-th character, not the start of string.
I guess a simple solution would be to split the string into a character array and then do the comparison?
For example something like:
Console.WriteLine("\nWrite a word/sentence: ");
char[] myString = Console.ReadLine().ToCharArray();
Console.Write("Type the character you would like to replace: ");
char myCharacter = Console.ReadLine().ToCharArray()[0];
int[] findIndex = new int[myString.Length];
int indexCount = 0;
for (int i = 0; i < myString.Length; i++)
{
if (myString[i] == myCharacter)
findIndex[indexCount++] = i;
}
for (int i = 0; i < indexCount; i++)
{
Console.Write(findIndex[i]);
}

Trying to add spaces between characters in a string in c#

I'm trying to add spaces between characters in a string in c#... Any advice would be very much appreciated.. Thanks
using System;
namespace nameReverser
{
class Program{
public static void Main(string[] args )
{ Console.WriteLine("Magical Name Reverser");
//User enters name
Console.WriteLine("Please Enter Your Name:");
string name = Console.ReadLine();
char[] cArray = name.ToCharArray();
string nameReversed = String.Empty;
for (int i= cArray.Length - 1; i>-1; i--)
{
nameReversed +=cArray[i];
}
Console.WriteLine("Your name in reverse order is:");
Console.WriteLine(nameReversed);
}
}
}
You can use String.Join to get a new string from array having a single space as separator. To print it in reverse order you can use Array.Reverse() hence your whole code will be like the following:
Console.WriteLine("Magical Name Reverser");
Console.WriteLine("Please Enter Your Name:");
string name = Console.ReadLine();
char[] cArray = name.ToCharArray();
Array.Reverse(cArray);
string resultString = String.Join(" ", cArray);
Console.WriteLine(resultString );
Console.WriteLine("Your name in reverse order is:");
Can be done in one-go
strResult= String.Join(" ", name.Reverse());
In addition to un-lucky's answer which adds spaces after each letter you can as well use the Insert() method of a string to add a space at a certain index
Example:
name = "Rudolf";
name.Insert (1, " ");
results to "R udolf"
Something like this
strResult= yourString(" ", name.Reverse());
Normally, I would recommend one of the other answers, if you only want to insert spaces into the string.
But in your example code, since you are looping through the string anyway, you can combine the reversal operation with the space insertion operation:
// ....
for (int i = cArray.Length - 1; i > -1; i--)
{
nameReversed += cArray[i] + " ";
}
// ...
Better yet, as suggested in the comments: if you are going to add to a string repeatedly, consider using a StringBuilder:
StringBuilder reverseBuilder;
for (int i = cArray.Length - 1; i > -1; i--)
{
reverseBuilder.Append(cArray[i]);
reverseBuilder.Append(' ');
}
// ...
nameReversed = reverseBuilder.ToString();
Slightly off subject...
If you want to add spaces between characters in a fixed width number like a time, you can also use the string format syntax:
int time = 1204; //represents 12:04
int hh = time / 100;
int mm = time - hh * 100;
string result = string.Format("{0:0 0} : {1:0 0}", hh, mm);
//result is 1 2 : 0 4

How to remove certain characters

I'm trying to remove single vowels from a string, but not if a vowel is double same.
For example string
"I am keeping a foobar"
should print out as
"m keepng foobr"
I have tried everything but didn't come up with a solution so far.
Try:
Regex.Replace(input, #"([aeiou])\1", "");
Though for I am keeping a foobar, it will give you m keepng foobr, which is different to your required m keepng foobr, as you're stripped spaces out of your required result, too.
If you want to remove the extraneous spaces, then it's a three step operation: remove vowels; remove proceeding/trailing spaces; remove double spaces.
var raw = Regex.Replace(input, #"([aeiou])\1", "");
var trimmed = raw.Trim();
var final = trimmed.Replace(" ", " ");
You could try this logic:
loop trough string and check two by two characters
if (isBothVowelsAndEqual()) do nothing; else removeFirstChar();
EDIT:
public List<char> vowels = "AEIOUaeiou".ToList();
public bool isBothVowelsAndEqual(char first, char second)
{
return (first == second && vowels.Contains(first));
}
const string s = "I am keeeping a foobar";
string output=String.Empty;
for (int i = 0; i < s.Length-1; i++)
{
if (isBothVowelsAndEqual(s[i], s[i + 1]))
{
output = output + s[i] + s[i+1];
i++;
}
else
{
if (!vowels.Contains(s[i])) {
output += s[i];
}
}
}
Console.WriteLine(output.Trim());

C#: Increment only the last number of a String

I have strings that look like this:
1.23.4.34
12.4.67
127.3.2.21.3
1.1.1.9
This is supposed to be a collection of numbers, separated by '.' symbols, similar to an ip address. I need to increment only the last digit/digits.
Expected Output:
1.23.4.35
12.4.68
127.3.2.21.4
1.1.1.10
Basically, increment whatever the number that is after the last '.' symbol.
I tried this:
char last = numberString[numberString.Length - 1];
int number = Convert.ToInt32(last);
number = number + 1;
If I go with the above code, I just need to replace the characters after the last '.' symbol with the new number. How do I get this done, good folks? :)
It seems to me that one method would be to:
split the string on . to get an array of components.
turn the final component into an integer.
increment that integer.
turn it back into a string.
recombine the components with . characters.
See, for example, the following program:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
String original = "1.23.4.34";
String[] components = original.Split('.');
int value = Int32.Parse(components[components.Length - 1]) + 1;
components[components.Length - 1] = value.ToString();
String newstring = String.Join(".",components);
Console.WriteLine(newstring);
}
}
}
which outputs the "next highest" value of:
1.23.4.35
You can use string.LastIndexOf().
string input = "127.3.2.21.4";
int lastIndex = input.LastIndexOf('.');
string lastNumber = input.Substring(lastIndex + 1);
string increment = (int.Parse(lastNumber) + 1).ToString();
string result = string.Concat(input.Substring(0, lastIndex + 1), increment);
You need to extract more than just the last character. What if the last character is a 9 and then you add 1 to it? Then you need to correctly add one to the preceding character as well. For example, the string 5.29 should be processed to become 5.30 and not simply 5.210 or 5.20.
So I suggest you split the string into its number sections. Parse the last section into an integer. Increment it and then create the string again. I leave it as an exercise for the poster to actually write the few lines of code. Good practice!
Something like this:
var ip = "1.23.4.34";
var last = int.Parse(ip.Split(".".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries).Last());
last = last + 1;
ip = string.Format("{0}.{1}",ip.Remove(ip.LastIndexOf(".")) , last);
If you are dealing with IP, there will be some extra code in case of .034, which should be 035 instead of 35. But that logic is not that complicated.
It's simple as this, use Split() and Join() String methods
String test = "1.23.4.34"; // test string
String[] splits = test.Split('.'); // split by .
splits[splits.Length - 1] = (int.Parse(splits[splits.Length - 1])+1).ToString(); // Increment last integer (Note : Assume all are integers)
String answ = String.Join(".",splits); // Use string join to make the string from string array. uses . separator
Console.WriteLine(answ); // Answer : 1.23.4.35
Using a bit of Linq
int[] int_arr = numberString.Split('.').Select(num => Convert.ToInt32(num)).ToArray();
int_arr[int_arr.Length - 1]++;
numberString = "";
for(int i = 0; i < int_arr.Length; i++) {
if( i == int_arr.Length - 1) {
numberString += int_arr[i].ToString();
}
else {
numberString += (int_arr[i].ToString() + ".");
}
}
Note: on phone so can't test.
My Solution is:
private static string calcNextCode(string value, int index)
{
if (value is null) return "1";
if (value.Length == index + 1) return value + "1";
int lastNum;
int myIndex = value.Length - ++index;
char myValue = value[myIndex];
if (int.TryParse(myValue.ToString(), NumberStyles.Integer, null, out lastNum))
{
var aStringBuilder = new StringBuilder(value);
if (lastNum == 9)
{
lastNum = 0;
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return calcNextCode(aStringBuilder.ToString(), index++);
}
else
{
lastNum++;
}
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return aStringBuilder.ToString();
}
return calcNextCode(value, index++);
}

Special characters Regex

Hello I'm try to remove special characters from user inputs.
public void fd()
{
string output = "";
string input = Console.ReadLine();
char[] charArray = input.ToCharArray();
foreach (var item in charArray)
{
if (!Char.IsLetterOrDigit(item))
{
\\\CODE HERE }
}
output = new string(trimmedChars);
Console.WriteLine(output);
}
At the end I'm turning it back to a string. My code only removes one special character in the string. Does anyone have any suggestions on a easier way instead
You have a nice implementation, just consider using next code, which is only a bit shorter, but has a little bit higher abstractions
var input = " th#ere's! ";
Func<char, bool> isSpecialChar = ch => !char.IsLetter(ch) && !char.IsDigit(ch);
for (int i = 1; i < input.Length - 1; i++)
{
//if current character is a special symbol
if(isSpecialChar(input[i]))
{
//if previous or next character are special symbols
if(isSpecialChar(input[i-1]) || isSpecialChar(input[i+1]))
{
//remove that character
input = input.Remove(i, 1);
//decrease counter, since we removed one char
i--;
}
}
}
Console.WriteLine(input); //prints " th#ere's "
A new string would be created each time you would call Remove. Use a StringBuilder for a more memory-performant solution.
The problem with your code is that you are taking the data from charArray and putting the result in trimmedChars for each change that you make, so each change will ignore all previous changes and work with the original. At the end you only have the last change.
Another problem with the code is that you are using IndexOf to get the index of a character, but that will get the index of the first occurance of that character, not the index where you got that character. For example when you are at the second ! in the string "foo!bar!" you will get the index of the first one.
You don't need to turn the string into an array to work with the characters in the string. You can just loop through the index of the characters in the string.
Note that you should also check the value of the index when you are looking at the characters before and after, so that you don't try to look at characters that are outside the string.
public void fd() {
string input = Console.ReadLine();
int index = 0;
while (index < input.Length) {
if (!Char.IsLetterOrDigit(input, index) && ((index == 0 || !Char.IsLetterOrDigit(input, index - 1)) || (index == input.Length - 1 || !Char.IsLetterOrDigit(input, index + 1)))) {
input = input.Remove(index, 1);
} else {
index++;
}
}
Console.WriteLine(input);
}
Been awhile since I've hit on C#, but a reg ex might be helpful
string input = string.Format("{0}! ", Console.ReadLine());
Regex rgx = new Regex("(?i:[^a-z]?)[.](?i:[^a-z]?)");
string output = rgx.Replace(input, "$1$2");
The regex looks for a character with a non-alpha character on left or right and replaces it with nothing.

Categories

Resources