2013-04-29 2 views
6

Следующая простая программа найдет последнюю букву в строке, которую пользователь вводит, а затем удаляет все после этой точки. Итак, если человек вводит один string.... все после удаления g. У меня есть следующий как маленькая программа:Удалить все символы после последнего письма

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(); 
    } 
} 

Я попытался многочисленные вариации этого и ни один из них не получить его именно писать. Эта конкретная программа со входом string.... выход программы strin.. Так что как-то он уходит от того, что он должен отнимать, и на самом деле убирает письма, которых это не должно. Может ли кто-нибудь указать, почему это происходит? Желаемый результат снова должен быть string.

+1

Почему бы просто не использовать 'input.Substring (0, x + 1)'? –

+0

@Grant Thomas: Потому что x может быть -1, если он не существует и все вычеркнуто, возможно, это намерение, это не совсем понятно из «spec». –

+0

@MichelKeijzers Это не имеет значения. Дело в том, что весь цикл является фарсом - валидация значения тривиальна. –

ответ

2

Я думаю, что это было бы гораздо более прямо вперед, чтобы просто Substringstring пользователь вошел. Таким образом, рассмотрим следующий измененный код:

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(); 
    } 
} 

здесь мы храним значение пользователь вошел в s, найти последний индекс письма, а затем Substring через эту букву при записи на консоль.

+0

Более элегантное решение проблемы, чем мое, я должен был бы сказать. +1 – wootscootinboogie

+0

@wootscootinboogie, спасибо большое! –

+0

Это приведет к поиску массива символов дважды. –

5

Попробуйте это:

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 
+0

+1 для элегантного решения, использующего LINQ. –

+0

+1 Нет необходимости в подстроке. 'String.Join (" ", input.TakeWhile (char.IsLetter))' – I4V

+0

Это не удастся! Это не будет искать последнюю букву, она будет искать первую NON-букву и удалить остальные, включая буквы, которые будут после нее. –

1

Вы также можете использовать функцию строки под названием SubString, чтобы получить все от первого до последнего индекса букв.

+0

Вы не знаете, что программа ведет себя так, как сейчас? – wootscootinboogie

+0

При удалении вы делаете: for (int i = x; i

3

Jsut для объяснения, потому что каждый раз, когда вы удаляете символ, вы увеличиваете счетчик i, а также уменьшаете charList.Count, чтобы вы фактически удаляли 1 символ, оставляя следующий, а затем удаляя снова и так далее. ..

Например, с входом «струна ....» и х 5 (индекс буквы G) вы делаете:

первой итерации: Удалите г полукокса так х становится 6 и charList.Count становится 9 (10-1)

Следующая итерация: Удалить символ в inde х 6, который теперь второй. (ваша строка "strin. . ..").

Итак, вы пропустили первый пункт.

Позвольте вам проверить другие ответы, поскольку они содержат более элегантные решения для ваших проблем.

+0

Это то, что я искал. Спасибо за это понимание, я уверен, что это поможет мне спуститься вниз. – wootscootinboogie

0

Это будет соответствовать каждое слово символа (AZ, 0-9 и _):

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 
+0

Связанная тема: http://stackoverflow.com/questions/3617797/regex-only-letters – Mecaveli

0

То, что я считаю, будет самым коротким, простым вариантом:

Edit: Комментарий Здесь указана начальная ошибка, поэтому я добавил небольшое исправление. Должно работать хорошо сейчас (не может быть оптимальным решением, но я думал, что это было весело простое решение в любом случае):

var userInput = Console.ReadLine(); 

Console.WriteLine(new string(userInput.Reverse() 
             .SkipWhile(c => !char.IsLetter(c)) 
             .Reverse() 
             .ToArray())); 
+0

Это не удастся! Это не будет искать последнюю букву, она будет искать первую NON-букву и удалить остальные, включая буквы, которые будут после нее. –

+0

@MartinMulder Спасибо, что указали, что вы были совершенно правы. Сейчас немного изменилось, поэтому я считаю, что теперь это должно быть правильно. – Kjartan

+0

Отлично ... но ... быть в курсе: этот ответ уже был представлен Мэтью Уотсоном. –

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

+1 для простого и элегантного – WiiMaxx

1

Вот довольно неэффективный способ это сделать (просто для удовольствия!)

var trimmedInput = string.Join("", input.Reverse().SkipWhile(x => !char.IsLetter(x)).Reverse()); 
+0

Если это так неэффективно, зачем его публиковать? –

+0

@MartinMulder «Просто для удовольствия». Возможно, это не твоя вещь! Но он демонстрирует некоторые применения Linq для обратной последовательности, что может представлять определенный интерес. –

1

Вы могли бы использовать это расширение:

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); 
} 

Вход: test...abc... Выход: test...abc

DEMO

1

Решение будет так.

string charList = "string..."; //any string place here 
int x = charList.LastIndexOf(charList.Last(char.IsLetter)); 
String str = charList.ToString().Substring(0, x + 1); 
Смежные вопросы