2014-01-31 11 views
0

Я хочу создать программу, которая берет введенную строку и переводит ее в другую строку, поэтому, если, например, я ввожу "Hello World", каждый символ превратится в строку, а консоль выведет что-то вроде "Alpha Beta Gamma Gamma Zeta Foxtrot Dona Rama Lana Zema" - каждый char a word.String to char to string

Я пытался делать это так:

static string WordMap(string value) 
{ 
    char[] buffer = value.ToCharArray(); 
    for (int i = 0; i < buffer.Length; i++) 
    { 
     if (letter = "a") 
     { 
      letter = ("Alpha"); 
     } 
     //and so on 

     buffer[i] = letter; 

    } 

    return new string(buffer);   

} 

, но я просто не могу заставить его работать. Может ли кто-нибудь дать мне подсказку или указать мне в правильном направлении?

+1

кто это письмо? ваш код, как показано, не компилируется – rla4

+3

Рассмотрите 'Словарь ' ... –

ответ

5

Что вам нужно, это Dictionary<char,string>

var words = new Dictionary<char, string>(); 
words.Add('a', "Alpha"); 
words.Add('b',"Beta"); 
... 
string input = Console.ReadLine(); 
string[] contents = new string[input.Length]; 
for (int i = 0; i < input.Length; i++) 
{ 
    if (words.ContainsKey(input[i])) 
    { 
     contents[i] = words[input[i]]; 
    } 
} 
string result = string.Join(" ", contents); 

LINQ Или так:

var result = string.Join(" ", input.Where(words.ContainsKey).Select(c => words[c])); 
+4

Или просто используйте LINQ: 'string result = string.Join (" ", input.Select (c => words [c ])); ' –

+0

@JonSkeet точно :), но все же мы должны использовать ContainsKey для предотвращения KeyNotFoundExceptin. Я думаю, –

+0

Потенциально. Это зависит от того, что вы хотите, чтобы режим отказа был :). Было бы разумно просто добавить это, хотя: 'input.Where (c => words.ContainsKey (c)). Выберите (...)'. О, и вы можете использовать инициализатор коллекции, чтобы сделать инициализацию словаря более чистым. –

0

Советы: Вы не должны создать массив символов из строки, вы можете легко получить доступ отдельных символов в строка индексатором:

char some = "123"[2]; 

При использовании «», то вы создаете строку не символ, следовательно, вы должны использовать «», чтобы создать символ для сравнения:

if (some == 'a') Console.WriteLine("character is a, see how you compare chars!!!"); 
+1

Почему вы используете 'ElementAt'? Вы пытались использовать LINQ, но вы используете метод расширения ElementAt самостоятельно! –

+0

@JonSkeet OP попросил совета, поэтому я хотел показать ему, что ему не нужно создавать массив символов. Во-вторых, он пытался сравнить символ с строкой. Это упростило бы работу OP. Это приведет к тому, что позже будет изучен словарь и LINQ. Я помню свои первые трудные времена с LINQ, поэтому я думаю, что человек, который задает такой вопрос, не нуждается в этом. Но ваша мысль о том, как это сделать, совершенно верна, поэтому я не отвечаю. – Mateusz

+0

Итак, просто покажите использование индексатора - это имеет смысл. Использование ElementAt является нечетным подходом и вполне может быть операцией O (n) ... Я бы удалил ее. –

1

Во-первых, буфер представляет собой массив символов. Массивы имеют фиксированный размер и для их расширения вам нужно создать новый. Чтобы преодолеть эту громоздкую работу, есть класс StringBuilder, который делает это автоматически.

Во-вторых, если вы сохраните эти «Альфа», «Бета», ... строки в утверждениях, у вас будет очень длинный фрагмент кода. Вы можете заменить это, используя словарь, или создать его из одной строки или текстового файла.

Чтобы поставить это на практике:

class MyClass 
{ 
    static Dictionary<char, string> _map = new Dictionary<char, string>(); 

    static MyClass() 
    { 
     _map.Add('a', "Alpha"); 
     _map.Add('b', "Beta"); 
     // etc 
    } 

    static string WordMap(string data) 
    { 
     var output = new StringBuilder(); 
     foreach (char c in data) 
     { 
      if (_map.ContainsKey(c)) 
      { 
       output.Append(_map[c]); 
       output.Append(' '); 
      } 
     } 
     return output.ToString(); 
    } 
} 

решение без словаря:

static string WordMap(string data) 
{ 
    const string words = "Alpha Beta Gamma Delta ..."; 

    string[] wordMap = words.Split(' '); 

    var output = new StringBuilder(); 
    foreach (char c in data) 
    { 
     int index = c - 'a'; 
     if (index >= 0 && index < wordMap.Length) 
     { 
      output.Append(wordMap[index]); 
      output.Append(' '); 
     } 
    } 
    return output.ToString(); 
} 
+0

В вашей второй части кода я думаю, что вы хотите, чтобы ваш оператор if был 'if (index> = 0 && index juharr

+0

Да, действительно, спасибо :) – Bas

+0

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

0

С помощью LINQ и String.Join это коротко и читаемым. Поскольку вы хотите иметь новое слово для специальных символов, вам нужна карта слов. Я хотел бы использовать Dictionary<char, string>:

static Dictionary<char, string> wordMap = new Dictionary<char, string>() 
{ 
    {'a', "Alpha"}, {'b', "Beta"},{'c', "Gamma"}, {'d', "Delta"} 
}; 

static string WordMap(string value) 
{ 
    var strings = value 
     .Select(c => 
     { 
      string word; 
      if(!wordMap.TryGetValue(c, out word)) 
       word = c.ToString(); 
      return word; 
     }); 
    return string.Join("", strings); 
} 

Тест:

string newString = WordMap("abcdeghj"); // AlphaBetaGammaDeltaeghj 
-1

Просто объявить вторую переменную, где вы строите свой результат. И я думаю, что у вас есть проблемы с синтаксисом, вам нужно иметь «==» в состоянии , иначе это назначение.

static string WordMap(string value) 
{ 
     string result = string.Empty; 
     char[] buffer = value.ToCharArray(); 
     for (int i = 0; i < buffer.Length; i++) 
     { 
      if (letter == "a") 
      { 
       result += ("Alpha"); 
      } 
      //and so on    

     } 

     return result;   
} 

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

result = string.Concat(result, "(Alpha)"); 

И еще более быстрый способ использует StringBuilder (с.документация для этого), , который предлагает вам быстрые и удобные способы обработки больших строк. Единственное падение здесь - это то, что вам нужно знать немного, насколько велика результат будет в символах, так как вам нужно предоставить начальное измерение. И здесь вам не следует начинать с 1 или 100. Каждый раз, когда StringBuilder заполнен, он создает новый больший экземпляр и копирует значения, поэтому множество экземпляров будут заполнять вашу память, что может вызвать исключение из памяти, при работе с несколькими десятками тысяч символов.

Но, как сказано, для просто для удовольствия кода, все это не имеет значения ... И, конечно же, вы должны знать, что если вы делаете это так, ваш результат будет быть в одной прямой линии, без перерывов. Если вы хотите разрывы строк, добавьте «\ n» в конце строки. Или добавьте что-нибудь, что вам нужно.

С уважением,

Markus

+1

Пожалуйста, объясните, как 'string.Concat (результат, «(Alpha)»); 'быстрее, чем' result + = («Alpha»); ' – Bas

+0

Действительно. Использование 'string.Join' однажды будет быстрее, как и при использовании' StringBuilder'. Предлагая повторные вызовы 'string.Concat', вы не понимаете, почему использование' + = 'выполняется медленно. Пожалуйста, прочитайте pobox.com/~skeet/csharp/stringbuilder.html –

+0

ну, честно говоря, вот что мне сказали на тренировках ... – mindfxxxedCoder

0

Хорошее решение ...

string[] words = { "Alpha", "Beta", "C_word", "D_Word" }; // .... 

    string myPhrase = "aBC"; 

    myPhrase.Replace(" ", string.Empty).ToList().ForEach(a => 
    { 
     int asciiCode = (int)a; 
     /// ToUpper() 
     int index = asciiCode >= 97 ? asciiCode - 32 : asciiCode; 
     Console.WriteLine(words[index - 65]); // ascii --> 65-a , 66-b ... 
    }); 
0

Еще одна вариация ответа, который содержит not found вариант.

static Dictionary<char, string> Mapping = 
    new Dictionary<char, string>() 
     { { 'a', "alpha" }, { 'b', "beta" }, { 'c', "gamma" }, { 'd', "zeta" } }; 

    static void Main(string[] args) 
    {    
     string test = "abcx"; 
     Console.WriteLine(string.Join(" ", test.Select(t => GetMapping(t)))); 
     //output alpha beta gamma not found   
     Console.ReadKey(); 
    } 

    static string GetMapping(char key) 
    { 
     if (Mapping.ContainsKey(key)) 
      return Mapping.First(a => a.Key == key).Value; 
     else 
      return "not found";    
    }