Алгоритм форматирования текста в Паскаль или верблюжий корпус - PullRequest
8 голосов
/ 28 августа 2008

Используя этот вопрос в качестве основы, приведен пример логики или кодирования для изменения текста на Pascal или Camel.

Например:

mynameisfred

становится

Camel: myNameIsFred
Pascal: MyNameIsFred

Ответы [ 2 ]

3 голосов
/ 28 августа 2008

Я нашел тему с группой парней из Perl, которые обсуждают этот вопрос на http://www.perlmonks.org/?node_id=336331.

Я надеюсь, что это не слишком большой ответ на вопрос, но я бы сказал, что у вас есть небольшая проблема в том, что это будет очень открытый алгоритм, который может иметь много ошибок 'а также хиты. Например, скажем, вы ввели: -

camelCase("hithisisatest");

Вывод может быть: -

"hiThisIsATest"

Или: -

"hitHisIsATest"

Нет алгоритма, который бы знал, какой из них выбрать. Вы можете добавить дополнительный код, чтобы указать, что вы предпочитаете более распространенные слова, но опять-таки произойдет промах (Питер Норвиг написал очень маленький корректор орфографии в http://norvig.com/spell-correct.html, который может помочь алгоритму мудро, я написал C # реализацию , если C # ваш язык).

Я бы согласился с Марком и сказал бы, что вам лучше иметь алгоритм, который принимает ввод с разделителями, то есть this_is_a_test и преобразует его. Это было бы просто реализовать, то есть в псевдокоде: -

SetPhraseCase(phrase, CamelOrPascal):
    if no delimiters
     if camelCase
      return lowerFirstLetter(phrase)
     else
      return capitaliseFirstLetter(phrase)
    words = splitOnDelimiter(phrase)
    if camelCase 
      ret = lowerFirstLetter(first word) 
     else
      ret = capitaliseFirstLetter(first word)
    for i in 2 to len(words): ret += capitaliseFirstLetter(words[i])
    return ret

capitaliseFirstLetter(word):
    if len(word) <= 1 return upper(word)
    return upper(word[0]) + word[1..len(word)]

lowerFirstLetter(word):
    if len(word) <= 1 return lower(word)
    return lower(word[0]) + word[1..len(word)]

Вы также можете заменить мою функцию capitaliseFirstLetter () надлежащим алгоритмом регистра, если хотите.

Реализация описанного выше алгоритма на C # выглядит следующим образом (полная консольная программа с тестовым набором): -

using System;

class Program {
  static void Main(string[] args) {

    var caseAlgorithm = new CaseAlgorithm('_');

    while (true) {
      string input = Console.ReadLine();

      if (string.IsNullOrEmpty(input)) return;

      Console.WriteLine("Input '{0}' in camel case: '{1}', pascal case: '{2}'",
        input,
        caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.CamelCase),
        caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.PascalCase));
    }
  }
}

public class CaseAlgorithm {

  public enum CaseMode { PascalCase, CamelCase }

  private char delimiterChar;

  public CaseAlgorithm(char inDelimiterChar) {
    delimiterChar = inDelimiterChar;
  }

  public string SetPhraseCase(string phrase, CaseMode caseMode) {

    // You might want to do some sanity checks here like making sure
    // there's no invalid characters, etc.

    if (string.IsNullOrEmpty(phrase)) return phrase;

    // .Split() will simply return a string[] of size 1 if no delimiter present so
    // no need to explicitly check this.
    var words = phrase.Split(delimiterChar);

    // Set first word accordingly.
    string ret = setWordCase(words[0], caseMode);

    // If there are other words, set them all to pascal case.
    if (words.Length > 1) {
      for (int i = 1; i < words.Length; ++i)
        ret += setWordCase(words[i], CaseMode.PascalCase);
    }

    return ret;
  }

  private string setWordCase(string word, CaseMode caseMode) {
    switch (caseMode) {
      case CaseMode.CamelCase:
        return lowerFirstLetter(word);
      case CaseMode.PascalCase:
        return capitaliseFirstLetter(word);
      default:
        throw new NotImplementedException(
          string.Format("Case mode '{0}' is not recognised.", caseMode.ToString()));
    }
  }

  private string lowerFirstLetter(string word) {
    return char.ToLower(word[0]) + word.Substring(1);
  }

  private string capitaliseFirstLetter(string word) {
    return char.ToUpper(word[0]) + word.Substring(1);
  }
}
0 голосов
/ 28 августа 2008

Единственный способ сделать это - пропустить каждую часть слова через словарь.

«mynameisfred» - это просто массив символов, разделение его на «мое имя Фред» означает понимание того, что означает объединение каждого из этих символов.

Вы могли бы сделать это легко, если бы ваш ввод был каким-то образом разделен, например, «меня зовут Фред» или «my_name_is_fred».

...