Chhabi Prasad Rana Ответов: 5

Строка реверсируется в предложении без реверсирования чисел.


Вход: 1 чашка горячего кофе стоит 8.00, в то время как холодный кофе стоит 45.00.
Выход: 1 puc fo toh eeffoc stsoc 8.00, saerehw dloc eeffoc stsoc 45.00.

Мне нужен метод, который вернет строку после обращения только алфавитов [a-zA-Z] в предложении, которое передается в качестве аргумента методу.

Что я уже пробовал:

static void Main(string[] args)
        {
            string str= ReverseWord("1 cup of hot coffee costs 8.00, whereas cold coffee costs 45.00.");
            Console.WriteLine(str);
            Console.ReadLine();
        }    

 static string ReverseWord(string originalString)
        {
            string[] splitStrings = originalString.Split(' ');
            int test = 0;
           // string result1 = string.Join(".", splitStrings);
            bool result = int.TryParse(splitStrings, out test);

            StringBuilder reverseWordString = new StringBuilder();
            List<char> charlist = new List<char>();
            for (int i = 0; i < originalString.Length; i++)
            {
                if (originalString[i] == ' ' || i == originalString.Length - 1 || result)
                {
                    if (i == originalString.Length - 1)
                        charlist.Add(originalString[i]);
                    for (int j = charlist.Count - 1; j >= 0; j--)
                        reverseWordString.Append(charlist[j]);
                    reverseWordString.Append(' ');
                    charlist = new List<char>();
                }
                else
                {
                    charlist.Add(originalString[i]);
                }
            }
            return reverseWordString.ToString();
        }

Patrice T

В чем проблема с этим кодом ?

Afzaal Ahmad Zeeshan

Звучит как вопрос для интервью/домашнего задания.

Где ты застрял?

PIEBALDconsult

Ищите же вы старые регулярные выражения. :Д

5 Ответов

Рейтинг:
26

F-ES Sitecore

Избавься от этого

 string[] splitStrings = originalString.Split(' ');
 int test = 0;
// string result1 = string.Join(".", splitStrings);
 bool result = int.TryParse(splitStrings, out test);

Вы проверяете, может ли массив строк быть проанализирован в int, чего он не может, этот код даже не будет компилироваться. Разделение на пробел, а затем проверка, будет ли он разбираться на int слово за словом, все равно не сработает, так как когда он доберется до 8.00, "слово" будет "8.00", которое не будет преобразовано в int (или decimal\double и т. д.).

Если вы прочтете вопрос немного внимательнее;

reversing only the alphabets [a-zA-Z]


затем посмотрите на свое состояние if;

if (originalString[i] == ' ' || i == originalString.Length - 1 || result)


Во-первых, избавьтесь от "результата", поскольку он теперь исчез (см. вступительный комментарий), а проверка на "" на самом деле не соответствует требованиям. Вместо этого вы хотите проверить, является ли это буквой (a-z), и если это так, то добавьте ее в charlist, а если нет, то добавьте обратную часть charlist в reverseWordString. Обновление "если" до

if (!char.IsLetter(originalString[i]) || i == originalString.Length - 1)


если вы начнете, то все, что вам нужно сделать, это изменить логику внутри этого утверждения "Если", чтобы сделать его проще на самом деле, все, что вам нужно сделать, это добавить обратную сторону charlist, а затем добавить символ, который не является буквой.


Рейтинг:
1

BillWoodruff

edit: оглядываясь назад, я думаю, что единственный способ сделать это надежным-это разобрать строку символ за символом. Следует ли 5.00 x визуализировать как x00.5, Как я делаю здесь, или выдать ошибку ?

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

private string StrReverse(string data)
{
    char[] splitchars = new char[] {' ','\t','\r','\n'};
    
    StringBuilder odata = new StringBuilder();
    
    string[] splitStrings = data.Split(splitchars, StringSplitOptions.RemoveEmptyEntries);
    
    double num;
    
    foreach (string str in splitStrings)
    {
        if (Double.TryParse(str, out num))
        {
            odata.Append(str);
        }
        else
        {
            // is the last char punctuation ?
            if(Char.IsPunctuation(str.Last()))
            {
                // can we make a number without trailing punctuation ?
                if (Double.TryParse(str.Substring(0, str.Length - 1), out num))
                {
                    // add it with trailing punctuation intact
                    odata.Append(str);
                }
                else
                {
                    // just reverse it
                    odata.Append(str.Reverse().ToArray());
                }
            }
            else
            {
                
                odata.Append(str.Reverse().ToArray());
            }
        }
    
        odata.Append(" ");
    }
    
    return odata.ToString();
}
Примечание: Я подозреваю, что использование регулярных выражений, как показано здесь пегим, может обрабатывать и другие возможные вариации.


PIEBALDconsult

В отсутствие более четкой спецификации я считаю, что "5.00 x" на "x00.5" неверно-вы переворачиваете неалфавитные символы.
Код операции может сделать это, но именно поэтому он просит о помощи.
"US$5.00" на "SU$5.00" может быть правильным, а может быть, это не должно быть изменено (я не знаю).
Что меня интригует, так это то, как относиться к чему-то вроде "пунктирного текста". Каким будет желаемый результат: без изменений , "dettod.txet" , "txet.dettod" , "txetde.ttod"
Я должен это знать!

BillWoodruff

:) "в отсутствие более четкой спецификации"

PIEBALDconsult

Мы еще не видели настоящего домашнего задания.

Рейтинг:
0

PIEBALDconsult

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

public static string
ReverseMatches
(
  string Input
,
  string Pattern
)
{
  System.Text.StringBuilder result = new System.Text.StringBuilder ( Input ) ;

  foreach
  (
    System.Text.RegularExpressions.Match m
  in
    System.Text.RegularExpressions.Regex.Matches ( Input , Pattern )
  )
  {
    for ( int i = 0 ; i < m.Length ; i++ )
    {
      result [ m.Index + i ] = m.Value [ m.Length - 1 - i ] ;
    }
  }

  return ( result.ToString() ) ;
}

string ouput = ReverseMatches ( "1 cup of hot coffee costs 8.00, whereas cold coffee costs 45.00." , "(?i)[A-Z]+" ) ;


BillWoodruff

+5 обрабатывает сохранение чисел, отформатированных должным образом.

Однако посмотрите на результат var rev = StrReverse("1 чашка горячего кофе стоит a8.00, тогда как холодный кофе стоит 45.00.");

PIEBALDconsult

Это не было включено в набор тестов.
Я предполагаю, что мой делает это правильно.
Он также не сохраняет пробелы (табуляции, множественные пробелы и т. д.).
Во всяком случае, более полная спецификация была бы приветствована.
И вы можете настроить регулярное выражение так, как считаете нужным. :Д

Рейтинг:
0

PIEBALDconsult

Может быть, именно этого и ожидал учитель/интервьюер:

public static string
ReverseAlpha
(
  string Input
)
{
  System.Text.StringBuilder result = new System.Text.StringBuilder ( Input.Length ) ;

  System.Collections.Generic.Stack<char> s = new System.Collections.Generic.Stack<char>() ;

  foreach ( char c in Input )
  {
    if ( System.Char.IsLetter ( c ) )
    {
      s.Push ( c ) ;
    }
    else
    {
      while ( s.Count > 0 )
      {
        result.Append ( s.Pop() ) ;
      }

      result.Append ( c ) ;
    }
  }

  while ( s.Count > 0 )
  {
    result.Append ( s.Pop() ) ;
  }

  return ( result.ToString() ) ;
}

string ouput = ReverseAlpha ( "1 cup of hot coffee costs 8.00, whereas cold coffee costs 45.00." ) ;


BillWoodruff

Рад видеть, что ты (возможно) исходя из моего анализа Чара на чар предложение :) Есть 5 !

PIEBALDconsult

:Д Да, вроде того.

Рейтинг:
0

OriginalGriff

Это не сложно: просто используйте двойной.Метод tryparse[^] чтобы увидеть, является ли "слово", которое вы преобразуете, числом, и если это так, не отменяйте его, а просто добавьте его к выходу.


George Swan

Если вы "разбили’ предложение на массив слов, используя символ пробела в качестве разделителя, вам нужно будет "обрезать" каждое слово перед тестированием на двойник. Кроме того, взгляните на "строку".Присоединяйтесь к методу воссоздания массива обрабатываемых слов в предложении. Что касается обращения струны вспять, то это просто вопрос поиска литературы – некоторые методы намного эффективнее других.

OriginalGriff

Эм ... нет.
Split отбрасывает символ split, к сожалению, поэтому "abc 123 def" будет отображаться как три обрезанные строки: "abc", "123" и "def".
Он не может использовать Join, чтобы перестроить его, потому что он должен изменить порядок символов большинства из них - вот почему он использует StringBuilder. Да, он мог бы использовать массив.Обратное для каждого слова, но это означает выделение нового пространства массива для каждого из них, что не является "быстрой" операцией.

George Swan

 string tester = "1 cup of hot coffee costs 8.00, whereas cold coffee costs 45.00.";
            string[] words = tester.Split(' ');
            List<string> reversedWords = new List<string>();
            foreach(var word in words)
            {
                 string trimmed = word.Trim(',', '.', ';');
                string s = double.TryParse(trimmed, out _) ? word : ReverseString(word);              
                    reversedWords.Add(s);              
            }
            var reversed = string.Join(" ", reversedWords);

PIEBALDconsult

Эй, у нас уже сто лет не было пятничного вызова кода... :D

BillWoodruff

Проблема двойная.Метод tryparse будет выполнена на задней символов в обоих 8.00, и 45.00. У пегого есть элегантное решение, и моя попытка "regex challenged" добавилась.